Чи є Safari на iOS 6 кешування результатів $ .ajax?


1072

З моменту оновлення до iOS 6, ми бачимо, що веб-перегляд Safari може вільно кешувати $.ajaxдзвінки. Це в контексті програми PhoneGap, тому він використовує Safari WebView. Наші $.ajaxвиклики - це POSTметоди, і кеш-пам'ять встановлена ​​на помилкову {cache:false}, але все-таки це відбувається. Ми намагалися вручну додати TimeStampзаголовки, але це не допомогло.

Ми провели більше досліджень і виявили, що Safari повертає лише кешовані результати для веб-служб, які мають підпис функції, який є статичним і не змінюється від виклику до виклику. Наприклад, уявіть функцію, яка називається щось на зразок:

getNewRecordID(intRecordType)

Ця функція отримує однакові вхідні параметри знову і знову, але дані, які вона повертає, повинні бути різними щоразу.

Повинно бути в поспіху Apple, щоб зробити iOS 6 zip вражаюче, вони надто задоволені налаштуваннями кешу. Хтось ще бачив таку поведінку на iOS 6? Якщо так, то що саме це викликає?


Ми знайшли рішення, щоб змінити функцію підпису таким чином:

getNewRecordID(intRecordType, strTimestamp)

а потім завжди передайте TimeStampпараметр і просто відкиньте це значення на стороні сервера. Це вирішує проблему. Я сподіваюся, що це допомагає іншій бідній душі, яка витрачає 15 годин на це питання, як я!


190
Це абсолютно шокує. Ми також просто провели пару годин, намагаючись розробити те, що щось просто перестало працювати. Наш AJAX логін, який робить POST (і має заголовки для запобігання кешування), кешується Safari, тому він просто повертає той самий JSON, що і минулого разу, навіть не намагаючись сервер ... неймовірний! Нам доведеться зламати виправлення, але ви ніколи не повинні кешувати POST, це божевільно.
Киеран

16
Опублікуйте своє рішення як відповідь, а не оновлення запитання.
ChrisF

50
POST-запити не ідентичні, а значить, їх не слід кешувати якщо відповідь спеціально не радить робити це через заголовки відповідей.
Джеймс М. Грін

6
Щоб Apple вирішила це, подайте помилку на сторінку bugreport.apple.com . Я зробив те саме.
Матіас Байненс

11
Марк Ноттінгем (голова робочої групи IETF HTTPbis) написав про це сьогодні цікавий пост у блозі: mnot.net/blog/2012/09/24/caching_POST
Бенджамін Бріцці

Відповіді:


447

Після невеликого розслідування виявляється, що Safari на iOS6 буде кешувати POST, які не мають або заголовків Cache-Control, або навіть "Cache-Control: max-age = 0".

Єдиний спосіб, який я знайшов, щоб запобігти тому, щоб кешування відбувалося на глобальному рівні, а не змушувати хакінгувати випадкові запити в кінці викликів служби, - це встановити "Кеш-контроль: без кешу".

Тому:

  • Заголовок кеш-керування або термін дії не закінчується = Safari iOS6 буде кешований
  • Кеш-контроль максимального віку = 0 і негайно закінчується = iOS6 Safari буде кешований
  • Кеш-контроль: no-cache = iOS6 Safari НЕ буде кешувати

Я підозрюю, що Apple користується цим із специфікації HTTP у розділі 9.5 про POST:

Відповіді на цей метод не підлягають кешуванню, якщо тільки відповідь не включає відповідні поля заголовка кеша або закінчується. Однак відповідь 303 (див. Інше) може бути використана для спрямування агента користувача на отримання кешованого ресурсу.

Тож теоретично ви можете кешувати відповіді POST ... хто знав. Але жоден інший виробник браузера досі не думав, що це було б хорошою ідеєю. Але це НЕ враховує кешування, якщо не встановлено заголовки Cache-Control або Expires, лише коли є деякий набір. Так що це має бути помилка.

Нижче наведено те, що я використовую в правому біті моєї конфігурації Apache, щоб орієнтуватися на весь мій API, оскільки, як це буває, насправді я не хочу нічого кешувати, навіть отримує. Я не знаю, як це встановити лише для постів.

Header set Cache-Control "no-cache"

Оновлення: Щойно помітив, що я не зазначив, що це лише тоді, коли POST однаковий, тож змініть будь-які дані POST або URL-адресу, і ви все в порядку. Таким чином, ви можете, як було зазначено в іншому місці, просто додати деякі випадкові дані до URL-адреси або трохи даних POST.

Оновлення: Ви можете обмежити "не кеш-пам'ять" лише POST, якщо ви хочете, як це в Apache:

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

7
Я бачу, куди Apple йде з цим, але ми бачимо кешовані відповіді на POST-запити навіть тоді, коли наші відповіді не включали заголовок Cache-Control або Expires. Цей екземпляр iOS6 не повинен кешувати та надсилати кожен запит. Цього не відбувається.
Kango_V

138
Частина специфікації HTTP, яку ви цитували, не виправдовує кешування поведінки iOS 6. Типовою поведінкою повинно бути не кешування відповідей POST (тобто коли заголовок "Кеш-контроль" не визначено). Поведінка порушує специфікацію і її слід вважати помилкою. Будь-хто, що будує веб-сервіси xml / json api, повинен прикрасити свої відповіді POST "Кеш-контроль: без кешу", щоб вирішити цю проблему.
Девід Н

39
Запити POST не ідентифікуються, а це означає, що вони не повинні кешуватися, якщо відповідь спеціально не радить робити це через заголовки відповідей.
Джеймс М. Грін

4
Як каже Девід, це явне порушення вироку, який ви цитували. Якщо немає пунктів заголовка кеш-керування або закінчується, відповідні такі заголовки, очевидно, не включаються. І все ж ваше власне розслідування показує, що воно зберігається в тому сценарії. Відредагуйте свою відповідь.
Меттью Флашен

3
Хто-небудь знає, як довго кешується результат на пристрої? Я намагався вбити сафарі та перезапустити телефон, але це все ще зберігається в кеші. Я знаю, що це працює з очищенням кешу браузера, але мені цікаво, скільки часу знадобиться користувачам, у яких колись виникли проблеми, перш ніж він пройде. Не кожен подумає очистити кеш-пам'ять ...
Даніель Холлквіст

146

Я сподіваюся, що це може бути корисно іншим розробникам, що вдаряють головою об стіну на цьому. Я виявив, що будь-яке з перерахованих вище перешкоджає Safari на iOS 6 кешувати відповідь POST:

  • додавання [кеш-контроль: немає кешу] у заголовки запитів
  • додавання параметра змінної URL-адреси, наприклад поточного часу
  • додавання [pragma: no-cache] у заголовки відповідей
  • додавання [кеш-контроль: без кешу] у заголовки відповідей

Моє рішення було таким у моєму Javascript (усі мої запити AJAX - POST).

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

Я також додаю заголовок [pragma: no-cache] до багатьох відповідей мого сервера.

Якщо ви використовуєте вищезазначене рішення, майте на увазі, що будь-які дзвінки $ .ajax (), які ви здійснюєте, встановлені на глобальний: false НЕ використовуватиме налаштування, визначені в $ .ajaxSetup (), тому вам потрібно буде знову додати заголовки.


4
Це ПРАВИЛЬНЕ рішення про помилку. Помилка в тому, що iOS 6 обслуговуватиме POST-запити з кешу, а не надсилати їх на сервер. Помилка не в тому, що вона кешує відповіді на POST-запити (що дозволено). Якщо ви все ще хочете відповіді на POST-запити, отримані з кешу для подальших GET-запитів до цього URI, використовуйте це рішення.
Ніколас Шенкс

2
Це працює для мене, але я не розумію як. Я вже вказав кеш: false в моєму ajaxSetup, і дивлячись на заголовки запитів, що зводиться до Cache-Control: no-cache та Pragma: no-cache - але він все одно кешуватиме на iPad. Потім, коли я додаю заголовки: {"cache-control": "no-cache"} в ajaxSetup, він подвоює заголовка кеша-керування на "no-cache, no-cache" - і зупиняє кешування. Що тут відбувається?
Том У Хол

Працює чудово - ви також можете додати до запиту параметр $ .ajax ({type: 'POST', заголовки: {'cache-control': 'no-cache'} тощо)}
Джордж Філіппакос,

Що таке [pragma: no-cache]? Для чого використовується прагма-ключ?
zakdances

Я також вважаю, що це найкращий підхід, а не обхід із додатковим параметром. Ми додали це лише за тими дзвінками, де нам це було потрібно, для дзвінків, які завжди мають однакову віддачу, кешування, ймовірно, є корисною справою для кінцевого користувача.
germankiwi

67

Просте рішення для всіх запитів вашої веб-служби, якщо ви користуєтесь 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()
    }));
});

Детальніше про дзвінок попереднього фільтра jQuery читайте тут .

Якщо ви не використовуєте jQuery, перевірте документи на вибір бібліотеки. Вони можуть мати подібний функціонал.


3
Мені це не працює, сервер відповідає: "Недійсний примітивний JSON: timeStamp" asp.net / iis 7.5
Александр,

3
що з $ .ajax ({"кеш": false ...})? чи буде вона працювати, додаючи _ = [TIMESTAMP]? (Я не володію таким пристроєм, щоб перевірити його)
Karussell

Я опублікував повну реалізацію рішення, запропонованого Карусселем. Дивіться мою відповідь нижче.
Сем Шилес

1
@Karussell. Щойно спробував встановити $ .ajax ({"кеш": false ...}). Це не вирішує проблему для POST-запитів на iOS6. Імовірно, оскільки JQuery відповідно до їхніх документів передбачає, що жоден браузер не є дурним, щоб кешувати запити на пошту. "Сторінки, отримані з POST, ніколи не кешуються, тому кеш і параметри ifModified в jQuery.ajaxSetup () не впливають на ці запити."
Бретт Ханна

1
Це не працює. Він не об'єднує параметри публікації. Пост Дейва - це краще рішення.
Кріс Мюнч

43

У мене просто виникло це питання також у додатку PhoneGap . Я вирішив це за допомогою функції JavaScript getTime()таким чином:

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

Я витратив кілька годин, з'ясовуючи це. Apple було б добре повідомити розробників про цю проблему кешування.


1
Я збирався прокоментувати використання {cache:false}в якості опції або $.post()або $.ajaxSetup(), але, згідно з документами , ці аргументи ігноруються; jQuery ніколи не кешуватиме публікації запитів, але не враховує браузер. Можливо, більш акуратним варіантом буде додати часову позначку до запитів із використанням $.ajaxPrefilter().
fwielstra

я витратити майже 5 годин , щоб вирішити цю проблему, і , нарешті , додавши мітку часу робитиме трюк function send_ajax(my_data,refresh) .. зверніться тут stackoverflow.com/questions/14733772 / ...
rusly

42

У мене була така ж проблема з веб-сервісом отримання даних з веб-сервісу ASP.NET

Це працювало для мене:

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

2
Дуже дякую! Я сходив з розуму, намагаючись зрозуміти, чому iPhone діє настільки інше, ніж будь-яка інша платформа. Це специфічне для ASP.NET рішення заощадило мені тону часу.
Марк Бріттінгем

Не працював на iOS6, дивіться мою відповідь наприкінці теми
Брайан Огден

1
Будь ласка !!!! Поставте умову застосовувати це лише на IOS 6, кеш вмісту є життєво важливим для будь-якої програми.
Олександр

24

Нарешті, я вирішив проблему із завантаженням.

У JavaScript:

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

На PHP :

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

15

З моєї власної публікації в блозі iOS 6.0 кешування запитів Ajax POST :

Як це виправити: Існують різні методи запобігання кешування запитів. Рекомендований метод - додавання заголовка без кешу. Ось як це робиться.

jQuery:

Перевірте iOS 6.0 і встановіть заголовок Ajax таким чином:

$.ajaxSetup({ cache: false });

ZeptoJS:

Перевірте iOS 6.0 і встановіть заголовок Ajax таким чином:

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

Сторона сервера

Java:

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

Не забудьте додати це вгорі сторінки, перш ніж будь-які дані будуть надіслані клієнту.

.NET

Response.Cache.SetNoStore();

Або

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.

2
Хороший атрибут без кешу для .NET stackoverflow.com/questions/10011780/…
Аран Малхолланд

7

Цей фрагмент JavaScript чудово працює з jQuery та jQuery Mobile:

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

Просто розмістіть його десь у вашому коді JavaScript (після завантаження jQuery, і найкраще, перш ніж робити запити AJAX), і це повинно допомогти.


6

Ви також можете вирішити цю проблему, змінивши функцію jQuery Ajax , виконавши наступні дії (станом на 1.7.1) вгорі функції Ajax (функція починається у рядку 7212). Ця зміна активує вбудовану функцію проти кешу jQuery для всіх POST-запитів.

(Повний сценарій доступний за адресою http://dl.dropbox.com/u/58016866/jquery-1.7.1.js.)

Вставити під рядок 7221:

if (options.type === "POST") {
    options.cache = false;
}

Потім змініть наступне (починаючи з рядка ~ 7497).

if (!s.hasContent) {
    // If data is available, append data to URL
    if (s.data) {
        s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
        // #9682: remove data so that it's not used in an eventual retry
        delete s.data;
    }

    // Get ifModifiedKey before adding the anti-cache parameter
    ifModifiedKey = s.url;

    // Add anti-cache in URL if needed
    if (s.cache === false) {
        var ts = jQuery.now(),
        // Try replacing _= if it is there
        ret = s.url.replace(rts, "$1_=" + ts);

        // If nothing was replaced, add timestamp to the end.
        s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
    }
}

До:

// More options handling for requests with no content
if (!s.hasContent) {
    // If data is available, append data to URL
    if (s.data) {
        s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
        // #9682: remove data so that it's not used in an eventual retry
        delete s.data;
    }

    // Get ifModifiedKey before adding the anti-cache parameter
    ifModifiedKey = s.url;
}

// Add anti-cache in URL if needed
if (s.cache === false) {
    var ts = jQuery.now(),
    // Try replacing _= if it is there
    ret = s.url.replace(rts, "$1_=" + ts);

    // If nothing was replaced, add timestamp to the end.
    s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
}

4
Це не дуже вдалий підхід до зміни jQuery або будь-якого коду, яким ви не володієте. (Кожен раз, коли ви хочете оновити версію, вам доведеться вносити зміни знову. (Або інший розробник оновлює і програма не працює))
andlrc

Це абсолютно вірний підхід, якщо вам потрібно найшвидше вирішити питання щодо пом’якшення ідіотизму Apple. Це рішення було використано для вирішення проблеми для масового веб-сайту, який отримує мільйони звернень на день, і це дозволило нам зробити це лише внести зміни в один файл.
Сем Шилес

Ви можете переглянути, jQuery.ajaxPrefilerщо дозволяє змінити запит на ajax безпосередньо перед тим, як зробити його. Ви можете архівувати те ж саме за допомогою оптимізованого та оновленого безпечного коду.
andlrc

1
Проблема підходу до фільтра полягає в тому, що вам потрібно зареєструвати фільтр. Якщо у вас є загальний сценарій, який працює під час завантаження кожної сторінки, то добре, але якщо ви цього не зробите, вам доведеться налаштувати preFilter для кожної сторінки, яка використовує ajax. У сценарії, з яким я стикався, у нас було спільне розташування файлу JQ, який використовувався як ресурс для 7+ окремих веб-сайтів. Ми втрачали тисячі фунтів на годину через цю помилку, і запропонований нами підхід дозволив нам вирішити її в найкоротші терміни, змінивши один файл. Я з вами принципово згоден, але іноді ви повинні бути прагматичними!
Сем Шилес

Потім ви можете знову додати його до кінця цього файлу. Добре, що ви це вирішили, ваша компанія повинна бути щасливою за вас.
andlrc

5

Швидке розв’язання послуг GWT-RPC полягає в тому, щоб додати це до всіх віддалених методів:

getThreadLocalResponse().setHeader("Cache-Control", "no-cache");

Більшість із нас мають сотні віддалених методів у своїх розгортаннях GWT. Чи існує універсальний спосіб встановити заголовок кеш-керування для всіх запитів?
dirkoneill

5

Це оновлення відповіді Баз1нга. Оскільки options.dataце не об'єкт, а рядок, я просто вдався до об'єднання часової позначки:

$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
  if (originalOptions.type == "post" || options.type == "post") {

    if (options.data && options.data.length)
      options.data += "&";
    else
      options.data = "";

    options.data += "timeStamp=" + new Date().getTime();
  }
});

1
Додавання часових позначок - це погана ідея, замість цього спробуйте рішення Дейва.
Ніколас Шенкс

4

Щоб вирішити цю проблему для WebApps, доданого на головний екран, потрібно дотримуватися обох найголовніших способів вирішення. Кешування потрібно вимкнути на веб-сервері, щоб запобігти подальшому кешування нових запитів, а до кожного запиту на пошту потрібно додати деякий випадковий ввід, щоб запити, які вже були кешовані, проходили. Будь ласка, зверніться до мого повідомлення:

iOS6 - Чи є спосіб очищення кешованих ajax запитів POST для веб-сайту, доданих на головний екран?

Попередження: всім, хто реалізував рішення, додавши позначку часу до своїх запитів, не вимикаючи кешування на сервері. Якщо додаток додано на головний екран, КОЖНА відповідь на повідомлення тепер буде кешована, очищення кеша сафарі не очистить його і, здається, не закінчується. Якщо хтось не має способу його очистити, це виглядає як потенційний витік пам'яті!


Чи будуть всі відповіді кешовані у файлі чи пам'яті телефону?
Ейдун

Зі мною такого не було. Я додав позначку часу до свого URL-адреси (не після параметрів), і він працює чудово, як під час перегляду сафарі, так і під час збереження на головний екран.
ShadeTreeDeveloper

4

Те, що не працювало для мене з iPad 4 / iOS 6:

Мій запит, що містить: Кеш-контроль: немає кешу

//asp.net's:
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache)

Додавання кеша: false для мого дзвінка ajax jQuery

 $.ajax(
        {
            url: postUrl,
            type: "POST",
            cache: false,
            ...

Тільки це зробило трюк:

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

Для чого голосування проти? Це важливий кеш інформації: false не працює з iPad4 / iOS6, а також не //asp.net: HttpContext.Current.Response.Cache.SetCacheability (HttpCacheability.NoCache)
Брайан Огден

Для нащадків: станом на 2017 рік $.ajax cache: falseдодає URL-адресу з параметром запиту _=Date.prototype.getTime(), тому додавання часової позначки вручну більше не потрібно.
ковбер

3

Ось така робота для GWT-RPC

class AuthenticatingRequestBuilder extends RpcRequestBuilder 
{
       @Override
       protected RequestBuilder doCreate(String serviceEntryPoint) 
       {
               RequestBuilder requestBuilder = super.doCreate(serviceEntryPoint);           
               requestBuilder.setHeader("Cache-Control", "no-cache");

               return requestBuilder;
       }
}

AuthenticatingRequestBuilder builder = new AuthenticatingRequestBuilder();
((ServiceDefTarget)myService).setRpcRequestBuilder(builder);    

2

Моє вирішення в ASP.NET (параметоди, веб-сервіс тощо)

protected void Application_BeginRequest(object sender, EventArgs e)
{
    Response.Cache.SetCacheability(HttpCacheability.NoCache);
}

1

Хоча додавання параметрів кеш-бустера для того, щоб запит виглядав інакше, схоже на надійне рішення, я б радив цього не сприймати, оскільки це зашкодить будь-якій програмі, яка покладається на фактичне кешування, що має місце. Зробити API виведення правильних заголовків є найкращим можливим рішенням, навіть якщо це трохи складніше, ніж додавати кестери кеша до абонентів.


1
Хоча я погодився б із вами більшістю обставин, я заперечую, що справжнє рішення цієї проблеми полягає в тому, щоб Apple правильно реалізувала HTTP. Зважаючи на це, я б не звинувачував багато розробників у впровадженні найпростішого можливого рішення до того часу. Для мене змінити реалізацію jquery було найпростішим виправленням, оскільки це дозволило мені зробити одну редакцію та бути впевненою, що вона активна для мого сайту.
Сем Шилес

1

Для тих, хто використовує Struts 1, ось як я виправив проблему.

web.xml

<filter>
    <filter-name>SetCacheControl</filter-name>
    <filter-class>com.example.struts.filters.CacheControlFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>SetCacheControl</filter-name>
    <url-pattern>*.do</url-pattern>
    <http-method>POST</http-method>
</filter-mapping>

com.example.struts.filters.CacheControlFilter.js

package com.example.struts.filters;

import java.io.IOException;
import java.util.Date;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;

public class CacheControlFilter implements Filter {

        public void doFilter(ServletRequest request, ServletResponse response,
                     FilterChain chain) throws IOException, ServletException {

        HttpServletResponse resp = (HttpServletResponse) response;
        resp.setHeader("Expires", "Mon, 18 Jun 1973 18:00:00 GMT");
        resp.setHeader("Last-Modified", new Date().toString());
        resp.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0");
        resp.setHeader("Pragma", "no-cache");

        chain.doFilter(request, response);
    }

    public void init(FilterConfig filterConfig) throws ServletException {
    }

    public void destroy() {
    }

}

1

Мені вдалося виправити свою проблему, використовуючи комбінацію $ .ajaxSetup та додавши часову позначку до URL моєї публікації (не до параметрів / тіла публікації). Це грунтується на рекомендаціях попередніх відповідей

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

    $('#myForm').submit(function() {
        var data = $('#myForm').serialize();
        var now = new Date();
        var n = now.getTime();
        $.ajax({
            type: 'POST',
            url: 'myendpoint.cfc?method=login&time='+n,
            data: data,
            success: function(results){
                if(results.success) {
                    window.location = 'app.cfm';
                } else {
                    console.log(results);
                    alert('login failed');
                }
            }
        });
    });
});

1

Я думаю, ви вже вирішили свою проблему, але дозвольте мені поділитися ідеєю щодо кешування веб-сторінок.

Це правда, що ви можете додати багато заголовків у кожній мові, яку ви використовуєте, на стороні сервера, на стороні клієнта, і ви можете використовувати багато інших хитрощів, щоб уникнути кешування веб-сторінок, але завжди думайте, що ви ніколи не можете знати, звідки клієнт підключається до вашого сервера, ви ніколи не знаєте, чи він використовує підключення до готелю "Hot-Spot", в якому використовуються кальмари або інші продукти кешування.

Якщо користувачі використовують проксі - сервер , щоб приховати своє справжнє становище, і т.д ... реальний єдиним способом кешування уникнути , є відміткою часу в запиті також , якщо не використовується.

Наприклад:

/ajax_helper.php?ts=3211321456

Тоді кожен кеш-менеджер, який вам потрібно буде пройти, не знайшов однакову URL-адресу в сховищі кешу і перезавантажив вміст сторінки.


Старий відповідь, але два мої центи: Це, як правило, хороша порада і розуміється більшістю компетентних веб-розробників, але в конкретному випадку jQuery, якщо ви зробите $.ajaxта встановили параметри, щоб {cache:false}тоді jQuery сам додасть перебір кешу за лаштунками, коли вам ніколи не потрібно нічого робити.
JakeGould

0

Залежно від програми ви можете вирішити проблему зараз у iOS 6 за допомогою Safari> Advanced> Web Inspector, що допоможе в цій ситуації.

Підключіть телефон до Safari на Mac, а потім скористайтеся меню розробника, щоб усунути проблеми з веб-додатком.

Очистіть дані веб-сайтів на iPhone після оновлення до iOS6, включаючи специфічні для програми програми Web View. Лише в одній програмі виникла проблема, і це вирішило її під час тестування бета-версії IOS6, оскільки з цього часу не виникало реальних проблем.

Можливо, вам також доведеться переглянути свій додаток, перевірити NSURLCache, якщо він є у WebView у власному додатку.

https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSURLCache_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40003754

Я думаю, залежно від справжнього характеру вашої проблеми, реалізації тощо.

Довідка: $ .ajax дзвінки


Хоча це не стосується безпосередньо початкового питання, це дуже корисна інформація для вирішення проблем із пристроями в цілому, тому я голосую за нього.
Kris Giesing

0

Я знайшов одне вирішення, яке мене цікавить, чому це працює. Перш ніж прочитати відповідь Тадея щодо веб-сервісу ASP.NET, я намагався придумати щось, що спрацювало б.

І я не кажу, що це гарне рішення, але я просто хотів це зафіксувати тут.

головна сторінка: включає функцію JavaScript, checkStatus (). Метод викликає інший метод, який використовує виклик jQuery AJAX для оновлення вмісту html. Я використовував setInterval для виклику checkStatus (). Звичайно, я зіткнувся з проблемою кешування.

Рішення: використовуйте іншу сторінку для виклику оновлення.

На головній сторінці я встановив булеву змінну, runUpdate та додав до тегу body таке:

<iframe src="helper.html" style="display: none; visibility: hidden;"></iframe>

На сторінці helper.html:

<meta http-equiv="refresh" content="5">
<script type="text/javascript">
    if (parent.runUpdate) { parent.checkStatus(); }
</script>

Отже, якщо callStatus () викликається з головної сторінки, я отримую кешований вміст. Якщо я дзвоню checkStatus з дочірньої сторінки, я отримую оновлений вміст.


0

Хоча сторінки мого входу та реєстрації працюють як шарм у Firefox, IE та Chrome ... Я боровся з цією проблемою в Safari для IOS та OSX, кілька місяців тому я знайшов вирішення проблеми SO.

<body onunload="">

АБО через javascript

<script type="text/javascript">
window.onunload = function(e){
    e.preventDefault();
    return;
};
</script>   

Це щось потворне, але працює деякий час.

Я не знаю чому, але повернувши нуль до onunloadподії, сторінка не буде кешована в Safari.


0

Ми виявили, що старі телефони iPhone та iPad, що працюють під управлінням iOS версії 9 та 10, періодично повертають фіктивні результати AJAX, можливо, через зниження швидкості процесора Apple. При поверненні порожнього результату iOS не викликає сервер, як би повертаючи результат з кешу. Частота коливається в широких межах - приблизно від 10% до 30% AJAX-дзвінків.

У рішення важко повірити. Просто зачекайте 1 і передзвоніть знову. У нашому тестуванні було лише одне повторення, що коли-небудь було потрібно, але ми написали код для виклику до 4 разів. Ми не впевнені, чи потрібен 1-й час очікування, але ми не хотіли ризикувати обтяжувати наш сервер спалахами повторних дзвінків.

Ми виявили, що ця проблема сталася з двома різними дзвінками AJAX, що викликали різні файли API з різними даними. Але я переживаю, що це може статися на будь-якому дзвінку AJAX. Ми просто не знаємо, оскільки не перевіряємо кожен результат AJAX і не тестуємо кожен виклик кілька разів на старих пристроях.

Обидва проблемні виклики AJAX використовували: POST, Asynchronically = true, setRequestHeader = ('Content-Type', 'application / x-www-form-urlencoded')

Коли проблема виникає, зазвичай відбувається лише один дзвінок AJAX. Тож це не через перекриття дзвінків AJAX. Іноді проблема трапляється, коли пристрій зайнятий, але іноді ні, і без DevTools ми не знаємо, що відбувається в цей час.

iOS 13 цього не робить, ні Chrome, ні Firefox. У нас немає тестових пристроїв під керуванням iOS 11 або 12. Можливо, хтось ще міг би протестувати їх?

Я зазначу це тут, тому що це питання є головним результатом Google при пошуку цієї проблеми.


-1

Він працював з ASP.NET лише після додавання pragma:no-cacheзаголовка в IIS . Cache-Control: no-cacheбуло недостатньо


-2

Я пропоную вирішити, щоб змінити функцію підпису таким чином:

getNewRecordID (intRecordType, strTimestamp), а також завжди передайте параметр TimeStamp, а також просто відкиньте це значення на стороні сервера. Це вирішує проблему.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.