iOS 6의 Safari는 $ .ajax 결과를 캐싱합니까?


1072

iOS 6으로 업그레이드 한 이후, Safari의 웹 뷰는 캐싱 $.ajax호출을 자유롭게 합니다. 이것은 PhoneGap 응용 프로그램과 관련이 있으므로 Safari WebView를 사용하고 있습니다. 우리의 $.ajax호출은 POST메소드이며 캐시를 false로 설정 {cache:false}했지만 여전히 발생합니다. TimeStamp헤더에 수동으로 a 를 추가하려고 시도했지만 도움이되지 않았습니다.

우리는 더 많은 연구를 해왔으며 Safari는 정적이며 서명마다 바뀌지 않는 함수 서명이있는 웹 서비스에 대해서만 캐시 된 결과를 반환한다는 것을 알았습니다. 예를 들어 다음과 같은 함수를 상상해보십시오.

getNewRecordID(intRecordType)

이 함수는 동일한 입력 매개 변수를 반복해서 수신하지만 반환되는 데이터는 매번 달라야합니다.

iOS 6 zip을 인상적으로 만들기 위해서는 Apple의 서둘러야합니다. 캐시 설정에 너무 만족했습니다. iOS 6에서이 동작을 본 사람이 있습니까? 그렇다면 정확히 원인은 무엇입니까?


우리가 찾은 해결 방법은 함수 서명을 다음과 같이 수정하는 것입니다.

getNewRecordID(intRecordType, strTimestamp)

그런 다음 항상 TimeStamp매개 변수도 전달 하고 서버 측에서 해당 값을 삭제하십시오. 이 문제를 해결합니다. 나는 이것이 내가했던 것처럼이 문제에 15 시간을 소비하는 다른 가난한 영혼을 도울 수 있기를 바랍니다!


190
이것은 절대 충격적입니다. 우리는 방금 일이 멈추었 던 것을 해결하기 위해 몇 시간을 보냈습니다. POST를 수행하고 캐싱을 방지하기 위해 헤더를 가진 AJAX 로그인은 Safari에 의해 캐시되므로 서버를 시도하지 않고도 지난번에했던 것과 동일한 JSON을 반환합니다 ... 믿을 수없는! 우리는 수정을 해킹해야하지만 POST를 캐시해서는 안됩니다.
Kieran

16
솔루션을 질문에 대한 업데이트가 아니라 답변으로 게시하십시오.
ChrisF

50
POST 요청은 비등 전성 이므로 응답이 응답 헤더를 통해 요청 하지 않는 한 캐시 되지 않아야 합니다.
James M. Greene

6
Apple에서이 문제를 해결하려면 bugreport.apple.com에 버그를 신고하십시오 . 나는 똑같이했다.
Mathias Bynens

11
Mark Nottingham (IETF HTTPbis 워킹 그룹의 회장)은 오늘 이것에 관한 흥미로운 블로그 글을 썼습니다 : mnot.net/blog/2012/09/24/caching_POST
Benjamin Brizzi

답변:


447

약간의 조사 결과, iOS6의 Safari는 Cache-Control 헤더가 없거나 "Cache-Control : max-age = 0"인 POST를 캐시합니다.

서비스 캐싱이 끝날 때 임의의 쿼리 문자열을 해킹하는 대신이 캐싱이 전역 수준에서 발생하지 않도록하는 유일한 방법은 "Cache-Control : no-cache"를 설정하는 것입니다.

그래서:

  • Cache-Control 또는 Expires 헤더 없음 = iOS6 Safari가 캐시합니다
  • Cache-Control max-age = 0 및 즉각적인 만료 = iOS6 Safari가 캐시합니다
  • 캐시 제어 : no-cache = iOS6 Safari는 캐시하지 않습니다

애플이 POST에 관한 섹션 9.5의 HTTP 스펙에서 이것을 활용하고 있다고 생각합니다.

응답에 적절한 Cache-Control 또는 Expires 헤더 필드가 포함되어 있지 않으면이 방법에 대한 응답을 캐시 할 수 없습니다. 그러나 303 (기타 참조) 응답을 사용하여 사용자 에이전트가 캐시 가능한 자원을 검색하도록 지시 할 수 있습니다.

이론적으로 POST 응답을 캐시 할 수 있습니다 ... 누가 알았습니다. 그러나 다른 브라우저 제작자는 지금까지 좋은 아이디어라고 생각한 적이 없습니다. 그러나 Cache-Control 또는 Expires 헤더가 설정되어 있지 않은 경우 일부 설정이있을 때만 캐싱을 설명하지 않습니다. 따라서 버그 여야합니다.

아래는 내가 아파치 구성의 올바른 비트에서 API 전체를 대상으로 사용하는 것입니다. 내가 모르는 것은 POST 용으로 이것을 설정하는 방법입니다.

Header set Cache-Control "no-cache"

업데이트 : POST가 동일 할 때만 지적 했으므로 POST 데이터 또는 URL을 변경하면 괜찮습니다. 따라서 다른 곳에서 언급했듯이 임의의 데이터를 URL 또는 약간의 POST 데이터에 추가하면됩니다.

업데이트 : Apache에서 다음과 같이 원하는 경우 "no-cache"를 POST로만 제한 할 수 있습니다.

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

7
Apple 이이 작업을 수행하는 위치를 알지만 응답에 Cache-Control 또는 Expires 헤더가 포함되어 있지 않은 경우에도 POST 요청에 대한 캐시 된 응답을보고 있습니다. 이 인스턴스는 iOS6이 모든 요청을 캐시하고 보내서는 안됩니다. 이것은 일어나지 않습니다.
Kango_V

138
인용 한 HTTP 사양의 일부는 iOS 6의 캐싱 동작을 정당화하지는 않습니다. 기본 동작은 POST 응답을 캐시하지 않아야합니다 (예 : "Cache-Control"헤더가 정의되지 않은 경우). 동작이 사양을 위반하므로 버그로 간주해야합니다. xml / json api 웹 서비스를 구축하는 사람은이 문제를 해결하기 위해 "Cache-control : no-cache"로 POST 응답을 장식해야합니다.
David H

39
POST 요청은 비등 전성 이므로 응답이 응답 헤더를 통해 요청 하지 않는 한 캐시 되지 않아야 합니다.
James M. Greene

4
David가 말했듯이 인용 한 문장을 명백히 위반 한 것입니다. "Cache-Control 또는 Expires 헤더 필드"가 없으면 해당 헤더가 포함되지 않은 것입니다. 그러나 귀하의 조사에 따르면 해당 시나리오에서 캐시됩니다. 답을 수정하십시오.
Matthew Flaschen

3
누구나 결과가 장치에 얼마나 오래 캐시되는지 알고 있습니까? 나는 사파리를 죽이고 전화를 다시 시작하려고 시도했지만 여전히 캐시되어 있습니다. 브라우저 캐시를 지우는 것이 효과적이라는 것을 알고 있지만 문제가 발생하기 전에 한 번 문제가 발생한 사용자에게는 시간이 얼마나 걸릴지 궁금합니다. 모두가 ... 자신의 캐시를 지우고 생각한다
다니엘 Hallqvist에게

146

나는 이것이 다른 개발자 가이 벽에 머리를 대고 사용할 수 있기를 바랍니다. 다음 중 하나가 iOS 6의 Safari가 POST 응답을 캐싱하는 것을 방지합니다.

  • 요청 헤더에 [cache-control : no-cache] 추가
  • 현재 시간과 같은 변수 URL 매개 변수 추가
  • 응답 헤더에 [pragma : no-cache] 추가
  • 응답 헤더에 [cache-control : no-cache] 추가

내 솔루션은 Javascript에서 다음과 같습니다 (모든 AJAX 요청은 POST입니다).

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

또한 많은 서버 응답에 [pragma : no-cache] 헤더를 추가합니다.

위의 솔루션을 사용하는 경우 global로 설정된 $ .ajax () 호출에 유의하십시오. false는 $ .ajaxSetup ()에 지정된 설정을 사용하지 않으므로 헤더를 다시 추가해야합니다.


4
이것이 버그에 대한 올바른 해결책입니다. 버그는 iOS 6이 POST 요청을 서버로 보내는 대신 캐시에서 서비스한다는 것입니다. 버그는 POST 요청의 응답을 캐시하는 것이 아닙니다 (허용됨). 해당 URI에 대한 후속 GET 요청에 대해 캐시에서 검색된 POST 요청에 대한 응답을 계속하려면이 솔루션을 사용하십시오.
니콜라스 생크

2
이것은 나를 위해 작동하지만 방법을 이해하지 못합니다. 이미 ajaxSetup에서 cache : false를 지정하고 요청 헤더를 보면 Cache-Control : no-cache 및 Pragma : no-cache로 요약되지만 여전히 iPad에서 캐시됩니다. 그런 다음 헤더를 추가하면 { "cache-control": "no-cache"} ajaxSetup에 Cache-Control 헤더가 "no-cache, no-cache"로 두 배가되고 캐싱이 중지됩니다. 여기서 무슨 일이야?
Tom W Hall

완벽하게 작동합니다. $ .ajax ({type : 'POST', 헤더 : { 'cache-control': 'no-cache'} 등) 매개 변수로 요청에 추가 할 수도 있습니다.
George Filippakos

[pragma : no-cache] 란 무엇입니까? pragma 키는 무엇에 사용됩니까?
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
Alexandre

3
$ .ajax ({ "cache": false ...})는 어떻습니까? _ = [TIMESTAMP]를 추가하면 작동합니까? (나는 그것을 테스트하는 그런 장치를 가지고 있지 않다)
Karussell

Karussell이 제안한 솔루션의 전체 구현을 게시했습니다. 아래 답변을 참조하십시오.
Sam Shiles

1
@ 카루셀. $ .ajax ({ "cache": false ...}) 설정을 시도했습니다. iOS6의 POST 요청 문제는 해결되지 않습니다. 아마도 문서에 따라 JQuery는 브라우저가 포스트 요청을 캐시 할만 큼 바보가 없다고 가정하기 때문입니다. "POST로 가져온 페이지는 캐시되지 않으므로 jQuery.ajaxSetup ()의 캐시 및 ifModified 옵션은 이러한 요청에 영향을 미치지 않습니다."
Brett Hannah

1
작동하지 않습니다. 게시물 매개 변수를 병합하지 않습니다. Dave의 게시물이 더 나은 솔루션입니다.
Chris Muench 2013 년

43

PhoneGap 응용 프로그램 에서도이 문제가 발생했습니다 . getTime()다음과 같은 방법으로 JavaScript 함수 를 사용하여 해결했습니다 .

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

나는 이것을 알아내는 데 몇 시간을 낭비했다. 이 캐싱 문제에 대해 개발자에게 알리는 것이 좋을 것입니다.


1
또는에 {cache:false}대한 옵션 으로 사용하는 것에 대해서는 언급하려고 했지만 문서 에 따르면 이러한 인수는 무시됩니다. jQuery는 게시 요청을 '캐시'하지 않지만 브라우저를 고려하지는 않습니다. 아마도 더 깔끔한 옵션은를 사용하여 요청에 타임 스탬프를 추가하는 것 입니다. $.post()$.ajaxSetup()$.ajaxPrefilter()
fwielstra

나는이 문제를 해결하는 데 거의 5 시간을 보내고 마지막으로 타임 스탬프를 추가하면 트릭을 수행합니다 function send_ajax(my_data,refresh) . stackoverflow.com/questions/14733772/…
rusly

42

ASP.NET 웹 서비스에서 데이터를 가져 오는 webapp와 동일한 문제가 있습니다.

이것은 나를 위해 일했다 :

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

2
대단히 감사합니다! 나는 왜 아이폰이 다른 플랫폼과 다르게 행동하는지 알아 내려고 미쳤다. 이 ASP.NET 관련 솔루션으로 많은 시간을 절약 할 수있었습니다.
Mark Brittingham

iOS6에서 작동하지 않았습니다. 스레드의 끝 부분에 대한 제 답변을보십시오.
Brian Ogden

1
부디!!!! IOS 6에서만이를 적용하는 조건을 설정하십시오. 컨텐츠 캐시는 모든 애플리케이션에 필수적입니다.
Alexandre

24

마지막으로 업로드 문제에 대한 해결책을 찾았습니다.

자바 스크립트에서 :

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) {…}

서버 측

자바:

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

데이터를 클라이언트에 보내기 전에 페이지 상단에 이것을 추가하십시오.

.그물

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'
    }
});

jQuery가로드 된 후 (AJAX 요청을하기 전에 가장 좋은) JavaScript 코드 어딘가에 배치하면 도움이됩니다.


6

또한 Ajax 함수 (7212 행에서 시작하는 함수)의 맨 위에서 다음 (1.7.1 현재)을 수행 하여 jQuery Ajax 함수를 수정하여이 문제를 해결할 수 있습니다 . 이 변경으로 모든 POST 요청에 대해 jQuery의 내장 된 캐시 방지 기능이 활성화됩니다.

(전체 스크립트는 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의 관용구를 완화하기 위해 가능한 한 빠른 솔루션이 필요한 경우 완벽하게 유효한 접근법입니다. 이 솔루션은 하루에 수백만 건의 조회수를받는 대규모 사이트의 문제를 해결하는 데 사용되었으며 하나의 파일 만 변경하면됩니다.
Sam Shiles

당신은 볼 수 jQuery.ajaxPrefiler당신이 그것을하기 전에 당신의 아약스 요청 권한을 수정할 수 있습니다. 보다 최적화되고 안전한 코드로 업데이트하여 보관할 수 있습니다.
andlrc

1
preFilter 접근 방식의 문제점은 필터를 등록해야한다는 것입니다. 각 페이지가로드 될 때 실행되는 공통 스크립트가 있다면 괜찮지 만 ajax를 사용하는 각 페이지마다 preFilter를 설정해야합니다. 내가 직면 한 시나리오에는 7 개 이상의 개별 웹 사이트에 대한 리소스로 사용 된 JQ 파일의 공통 위치가있었습니다. 우리는이 버그로 인해 시간당 수천 파운드를 잃었고, 내가 제안한 접근 방식으로 ONE 파일을 변경하여 가능한 한 가장 짧은 시간에 문제를 해결할 수있었습니다. 나는 원칙적으로 당신에 동의하지만 때로는 실용적이어야합니다!
Sam Shiles

그런 다음 해당 파일의 끝에 다시 추가 할 수 있습니다. 당신이 그것을 잘 해결, 당신의 회사는 당신을 위해 행복해야합니다.
andlrc

5

GWT-RPC 서비스의 빠른 해결 방법은이 방법을 모든 원격 방법에 추가하는 것입니다.

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

우리 대부분은 GWT 배포에 수백 개의 원격 메소드를 가지고 있습니다. 모든 요청에 ​​대해 캐시 제어 헤더를 설정하는 보편적 인 방법이 있습니까?
dirkoneill

5

Baz1nga의 답변이 업데이트되었습니다. 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
타임 스탬프를 추가하는 것은 좋지 않습니다. 대신 Dave의 솔루션을 사용해보십시오.
니콜라스 생크

4

홈 화면에 추가 된 WebApp에 대해이 문제를 해결하려면 가장 많이 투표 된 해결 방법을 따라야합니다. 새로운 요청이 캐시되는 것을 방지하기 위해 웹 서버에서 캐싱을 꺼야하며 이미 캐시 된 요청이 통과하려면 모든 포스트 요청에 임의의 입력을 추가해야합니다. 내 게시물을 참조하십시오 :

iOS6-홈 화면에 추가 된 webapp에 대한 캐시 된 ajax POST 요청을 지우는 방법이 있습니까?

경고 : 서버에서 캐싱을 끄지 않고 요청에 타임 스탬프를 추가하여 해결 방법을 구현 한 사람에게. 앱이 홈 화면에 추가되면 모든 게시물 응답이 이제 캐시되므로 사파리 캐시를 지워도 지워지지 않고 만료되지 않는 것 같습니다. 누군가가 그것을 지우는 방법이 없다면, 이것은 잠재적 인 메모리 누수처럼 보입니다!


모든 응답이 전화의 파일 또는 메모리에 캐시됩니까?
Eydun

이것은 나에게 해당되지 않았습니다. URL에 시간 스탬프를 추가했는데 (포스트 매개 변수 아님) 사파리에서 탐색 할 때와 홈 화면에 저장할 때 모두 잘 작동합니다.
ShadeTreeDeveloper

4

작동 하지 않는iPad 4 / iOS 6에서 나에게 효과가 :

내 요청에 포함 : Cache-Control : no-cache

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

캐시 추가 : jQuery ajax 호출에 false

 $.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)
Brian Ogden

후손의 경우 : 2017 년 기준으로 $.ajax cache: falseURL에 query 매개 변수 _=Date.prototype.getTime()를 추가하므로 수동으로 타임 스탬프를 추가 할 필요가 없습니다.
cowbert

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 구현을 수정하는 것이 가장 간단한 수정이었습니다. 하나의 편집 작업을 수행하고 전체 사이트에서 활성화되었다고 확신 할 수있었습니다.
Sam Shiles

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

이미 문제를 해결했다고 생각하지만 웹 캐싱에 대한 아이디어를 공유하겠습니다.

서버 측, 클라이언트 측에서 사용하는 각 언어로 많은 헤더를 추가 할 수 있으며 웹 캐싱을 피하기 위해 다른 많은 트릭을 사용할 수 있지만 항상 클라이언트가 서버에 연결된 위치를 알 수는 없다고 생각하십시오. 그가 Squid 또는 다른 캐싱 제품을 사용하는 Hotel "Hot-Spot"연결을 사용하고 있는지 절대 알 수 없습니다.

사용자가 자신의 실제 위치를 숨기기 위해 프록시를 사용하는 경우 등 ... 실제 피하기 캐싱 유일한 방법은 사용되지도 경우 요청의 타임 스탬프입니다.

예를 들면 다음과 같습니다.

/ajax_helper.php?ts=3211321456

그런 다음 전달 해야하는 모든 캐시 관리자가 캐시 저장소에서 동일한 URL을 찾지 못하고 페이지 내용을 다시 다운로드하십시오.


오래된 대답이지만 내 두 센트 : 이것은 일반적으로 좋은 조언이며 대부분의 유능한 웹 개발자가 이해하지만 jQuery의 특정 경우 $.ajax에는 옵션을 설정하고 {cache:false}jQuery 자체가 자동으로 캐시 무효화를 추가합니다 다른 일을 할 필요없이 무대 뒤에서.
JakeGould

0

앱에 따라 Safari> Advanced> Web Inspector를 사용하여 iOS 6에서 문제를 해결할 수 있으므로이 상황에 도움이됩니다.

Mac에서 휴대폰을 Safari에 연결 한 다음 개발자 메뉴를 사용하여 웹 앱을 촬영하는 데 문제가 있습니다.

웹보기를 사용하는 앱별 정보를 포함하여 iOS6으로 업데이트 한 후 iPhone에서 웹 사이트 데이터를 지우십시오. 하나의 앱에만 문제가 있었으므로 IOS6 베타 테스트 중에 문제가 해결되었으므로 실제 문제는 없었습니다.

사용자 정의 앱의 WebView에 있으면 NSURLCache를 확인하십시오.

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 웹 서비스에 관한 Tadej의 답변을 읽기 전에 나는 작동하는 것을 생각해 냈습니다.

그리고 그것이 좋은 해결책이라고 말하지는 않지만 여기에 문서화하고 싶었습니다.

메인 페이지 : 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>

따라서 메인 페이지에서 checkStatus ()를 호출하면 캐시 된 내용을 얻습니다. 자식 페이지에서 checkStatus를 호출하면 업데이트 된 내용이 표시됩니다.


0

내 로그인 및 가입 페이지가 Firefox, IE 및 Chrome에서 매력처럼 작동하는 동안 몇 달 전에 IOS 및 OSX 용 Safari에서이 문제로 어려움을 겪고 있습니다.

<body onunload="">

또는 자바 스크립트를 통한

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

이것은 약간 추한 일이지만 잠시 동안 작동합니다.

이유를 모르겠지만 onunloadSafari에서 페이지가 캐시되지 않는 이벤트에 null을 반환 합니다.


0

iOS 버전 9 및 10을 실행하는 구형 iPhone 및 iPad는 때때로 Apple의 CPU 속도 저하로 인해 허위 빈 AJAX 결과를 반환합니다. 빈 결과를 반환하면 iOS는 캐시에서 결과를 반환하는 것처럼 서버를 호출하지 않습니다. 빈도는 AJAX 통화의 약 10 %에서 30 %까지 공백으로 반환됩니다.

해결책은 믿기 어렵습니다. 1 초만 기다렸다가 다시 전화하십시오. 테스트에서 한 번만 반복하면되었지만 최대 4 번 호출하는 코드를 작성했습니다. 1s 대기가 필요한지 확실하지 않지만 반복되는 호출로 서버에 부담을 줄 위험은 없습니다.

데이터가 다른 다른 API 파일을 호출하는 두 개의 다른 AJAX 호출에서 문제가 발생했습니다. 그러나 AJAX 호출에서 발생할 수 있다고 걱정합니다. 우리는 모든 AJAX 결과를 검사하지 않고 오래된 장치에서 모든 호출을 여러 번 테스트하지 않기 때문에 알 수 없습니다.

두 가지 AJAX 호출 문제 : POST, Asynchronously = true, setRequestHeader = ( 'Content-Type', 'application / x-www-form-urlencoded')

문제가 발생하면 일반적으로 AJAX 호출이 하나만 발생합니다. 따라서 AJAX 호출이 겹치지 않기 때문입니다. 때로는 장치가 바쁠 때 문제가 발생하지만 때로는 그렇지 않으며 DevTools가 없으면 당시에 무슨 일이 일어나고 있는지 실제로 알지 못합니다.

iOS 13 은이 작업을 수행하지 않으며 Chrome 또는 Firefox도 수행하지 않습니다. iOS 11 또는 12를 실행하는 테스트 장치가 없습니다. 다른 사람이 테스트 할 수 있습니까?

이 질문은이 문제를 검색 할 때 최고의 Google 결과이므로 여기에 주목합니다.


-1

IIS 에서 헤더를 추가 한 후에 만 ASP.NET에서 작동했습니다 . 충분하지 않았다.pragma:no-cacheCache-Control: no-cache


-2

함수 서명을 다음과 같이 수정하는 해결 방법을 제안합니다.

getNewRecordID (intRecordType, strTimestamp) 다음 항상 TimeStamp 매개 변수를 전달하고 서버 측에서 해당 값을 버립니다. 이 문제를 해결합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.