Pertanyaan Apakah Safari di iOS 6 cache $ .ajax hasil?


Sejak upgrade ke iOS 6, kami melihat tampilan web Safari mengambil kebebasan dari caching $.ajax panggilan. Ini dalam konteks aplikasi PhoneGap sehingga menggunakan Safari WebView. Kami $.ajax panggilan adalah POST metode dan kami memiliki cache diatur ke false {cache:false}, tapi tetap saja ini terjadi. Kami mencoba menambahkan secara manual a TimeStamp ke header tetapi itu tidak membantu.

Kami melakukan lebih banyak penelitian dan menemukan bahwa Safari hanya mengembalikan hasil cache untuk layanan web yang memiliki tanda tangan fungsi yang statis dan tidak berubah dari panggilan ke panggilan. Misalnya, bayangkan suatu fungsi yang disebut sesuatu seperti:

getNewRecordID(intRecordType)

Fungsi ini menerima parameter input yang sama berulang kali, tetapi data yang dihasilkannya harus berbeda setiap kali.

Harus dengan terburu-buru Apple untuk membuat iOS 6 zip secara mengesankan mereka terlalu senang dengan pengaturan cache. Adakah orang lain yang melihat perilaku ini di iOS 6? Jika ya, apa sebenarnya penyebabnya?


Solusi yang kami temukan adalah mengubah tanda tangan fungsi menjadi sesuatu seperti ini:

getNewRecordID(intRecordType, strTimestamp)

dan kemudian selalu lulus dalam TimeStamp parameter juga, dan buang nilai itu di sisi server. Ini bekerja di sekitar masalah ini. Saya harap ini membantu beberapa jiwa miskin lainnya yang menghabiskan 15 jam untuk masalah ini seperti yang saya lakukan!


1029
2017-09-20 06:07


asal


Jawaban:


Setelah sedikit penyelidikan, ternyata Safari di iOS6 akan meng-cache POST yang tidak memiliki header Cache-Control atau bahkan "Cache-Control: max-age = 0".

Satu-satunya cara saya menemukan mencegah caching ini terjadi di tingkat global daripada harus meretas querystrings acak ke akhir panggilan layanan adalah dengan mengatur "Cache-Control: no-cache".

Begitu:

  • Tidak ada header Cache-Control atau Kedaluwarsa = Safari iOS6 akan menyimpan cache
  • Cache-Control max-age = 0 dan Expires segera = Safari iOS6 akan cache
  • Cache-Control: no-cache = iOS6 Safari TIDAK akan menyimpan cache

Saya menduga bahwa Apple mengambil keuntungan dari ini dari spesifikasi HTTP di bagian 9.5 tentang POST:

Tanggapan terhadap metode ini tidak dapat di-cache, kecuali respons      termasuk kolom header Cache-Control atau Expires yang sesuai. Namun,      respons 303 (Lihat Lainnya) dapat digunakan untuk mengarahkan agen pengguna ke      mengambil sumber daya yang dapat disimpan dalam cache.

Jadi dalam teori Anda dapat meng-cache tanggapan POST ... siapa yang tahu. Tetapi tidak ada pembuat browser lain yang pernah berpikir itu akan menjadi ide yang baik sampai sekarang. Tapi itu TIDAK menjelaskan cache ketika tidak ada header Cache-Control atau Kedaluwarsa yang ditetapkan, hanya ketika ada beberapa set. Jadi itu pasti bug.

Di bawah ini adalah apa yang saya gunakan di bit kanan dari konfigurasi Apache saya untuk menargetkan seluruh API saya karena saat itu terjadi saya tidak benar-benar ingin menyimpan apa pun, bahkan mendapat. Yang tidak saya ketahui adalah bagaimana mengatur ini hanya untuk POST.

Header set Cache-Control "no-cache"

Pembaruan: Hanya perhatikan bahwa saya tidak menunjukkan bahwa hanya ketika POST sama, jadi ubahlah salah satu data atau URL POST dan Anda baik-baik saja. Jadi Anda bisa seperti yang disebutkan di tempat lain hanya menambahkan beberapa data acak ke URL atau sedikit data POST.

Pembaruan: Anda dapat membatasi "no-cache" hanya ke POST jika Anda menginginkan seperti ini di Apache:

SetEnvIf Request_Method "POST" IS_POST
Header set Cache-Control "no-cache" env=IS_POST

434
2017-09-20 16:06



Saya harap ini bisa berguna bagi pengembang lain membenturkan kepala mereka terhadap dinding yang satu ini. Saya menemukan bahwa hal-hal berikut ini mencegah Safari di iOS 6 dari caching respons POST:

  • menambahkan [kontrol-cache: tanpa-cache] di header permintaan
  • menambahkan parameter URL variabel seperti waktu saat ini
  • menambahkan [pragma: no-cache] di header respons
  • menambahkan [kontrol-cache: tanpa-cache] di header respons

Solusi saya adalah yang berikut dalam Javascript saya (semua permintaan AJAX saya adalah POST).

$.ajaxSetup({
    type: 'POST',
    headers: { "cache-control": "no-cache" }
});

Saya juga menambahkan header [pragma: no-cache] ke banyak tanggapan server saya.

Jika Anda menggunakan solusi di atas, ketahuilah bahwa setiap $ .ajax () panggilan yang Anda buat yang disetel ke global: false TIDAK akan menggunakan pengaturan yang ditentukan dalam $ .ajaxSetup (), jadi Anda harus menambahkan header lagi.


143
2017-10-12 09:56



Solusi sederhana untuk semua permintaan layanan web Anda, dengan asumsi Anda menggunakan jQuery:

$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
    // you can use originalOptions.type || options.type to restrict specific type of requests
    options.data = jQuery.param($.extend(originalOptions.data||{}, { 
      timeStamp: new Date().getTime()
    }));
});

Baca lebih lanjut tentang panggilan prefilter jQuery sini.

Jika Anda tidak menggunakan jQuery, periksa dokumen untuk perpustakaan pilihan Anda. Mereka mungkin memiliki fungsi yang serupa.


64
2017-09-21 08:53



Saya memiliki masalah yang sama dengan webapp mendapatkan data dari webservice ASP.NET

Ini berhasil untuk saya:

public WebService()
{
    HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    ...
}

40
2017-09-20 21:28



Saya baru saja memiliki masalah ini juga di a PhoneGap aplikasi. Saya memecahkannya dengan menggunakan fungsi JavaScript getTime() dengan cara berikut:

var currentTime = new Date();
var n = currentTime.getTime();
postUrl = "http://www.example.com/test.php?nocache="+n;
$.post(postUrl, callbackFunction);

Aku menyia-nyiakan beberapa jam untuk memikirkan hal ini. Akan sangat menyenangkan bagi Apple untuk memberi tahu pengembang tentang masalah cache ini.


40
2017-09-20 07:34



Akhirnya, saya punya solusi untuk masalah pengunggahan saya.

Di JavaScript:

var xhr = new XMLHttpRequest();
xhr.open("post", 'uploader.php', true);
xhr.setRequestHeader("pragma", "no-cache");

Di PHP:

header('cache-control: no-cache');

22
2017-09-22 10:16



Dari posting blog saya sendiri iOS 6.0 cache Ajax POST permintaan:

Cara memperbaikinya: Ada berbagai metode untuk mencegah caching permintaan. Metode yang disarankan adalah menambahkan header no-cache. Beginilah caranya.

jQuery:

Periksa iOS 6.0 dan atur header Ajax seperti ini:

$.ajaxSetup({ cache: false });

ZeptoJS:

Periksa iOS 6.0 dan atur header Ajax seperti ini:

$.ajax({
    type: 'POST',
    headers : { "cache-control": "no-cache" },
    url : ,
    data:,
    dataType : 'json',
    success : function(responseText) {…}

Sisi server

Jawa:

httpResponse.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");

Pastikan untuk menambahkan ini di bagian atas halaman sebelum data dikirim ke klien.

.BERSIH

Response.Cache.SetNoStore();

Atau

Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);

PHP

header('Cache-Control: no-cache, no-store, must-revalidate'); // HTTP 1.1.
header('Pragma: no-cache'); // HTTP 1.0.

14
2017-11-14 06:02



Cuplikan JavaScript ini berfungsi baik dengan jQuery dan jQuery Mobile:

$.ajaxSetup({
    cache: false,
    headers: {
        'Cache-Control': 'no-cache'
    }
});

Tempatkan saja di suatu tempat di kode JavaScript Anda (setelah jQuery dimuat, dan terbaik sebelum Anda melakukan permintaan AJAX) dan itu akan membantu.


7
2018-01-25 22:11