iOS 6의 Safari는 $ .ajax 결과를 캐싱합니까? 서명이있는 웹

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 시간을 소비하는 다른 가난한 영혼을 도울 수 있기를 바랍니다!



답변

약간의 조사 결과, 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


답변

나는 이것이 다른 개발자 가이 벽에 머리를 대고 사용할 수 있기를 바랍니다. 다음 중 하나가 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 ()에 지정된 설정을 사용하지 않으므로 헤더를 다시 추가해야합니다.


답변

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를 사용하지 않는 경우 선택한 라이브러리에 대한 문서를 확인하십시오. 그것들은 비슷한 기능을 가지고있을 수 있습니다.


답변

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

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

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


답변

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

이것은 나를 위해 일했다 :

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


답변

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

자바 스크립트에서 :

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

에서 PHP :

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


답변

내 블로그 게시물에서 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.