iOS 6의 Safari는 $.ajax 결과를 캐싱하고 있습니까?

iOS 6로의 업그레이드 이후 Safari의 웹 뷰는 자유롭게 캐싱할 수 있게 되었습니다.$.ajax이것은 PhoneGap 어플리케이션의 컨텍스트이기 때문에 Safari WebView를 사용하고 있습니다.우리들의$.ajax콜은POST캐시가 false로 설정되어 있습니다.{cache:false}하지만 여전히 일어나고 있습니다.수동으로 추가하려고 했습니다.TimeStamp머리글에 표시했지만 도움이 되지 않았습니다.

조사 결과, Safari는 기능 시그니처가 정적이고 콜마다 변경되지 않는 웹 서비스에 대해서만 캐시된 결과를 반환하는 것으로 나타났습니다.예를 들어 다음과 같은 함수를 상상해 보십시오.

getNewRecordID(intRecordType) 

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

Apple이 iOS 6를 빠르게 만들기 위해 서두른 것이 분명합니다. 그들은 캐시 설정에 너무 만족했습니다.iOS 6에서 이 동작을 본 사람이 있습니까? 그렇다면 정확히 무엇이 원인입니까?


이 문제를 해결하려면 함수 시그니처를 다음과 같이 수정해야 합니다.

getNewRecordID(intRecordType, strTimestamp) 

그리고 항상 통과합니다.TimeStamp서버측에서 그 값을 파기합니다.이 문제는 회피할 수 있습니다.



질문에 대한 답변



조사 결과 iOS6의 Safari는 Cache-Control 헤더가 없거나 심지어 “Cache-Control: max-age=0″이 없는 POST를 캐시합니다.

서비스 콜 종료 시 랜덤 쿼리 스트링을 해킹하지 않고 글로벌레벨에서 이 캐싱이 발생하지 않도록 하는 유일한 방법은 “Cache-Control: no-cache”를 설정하는 것입니다.

그래서:

  • 캐시 제어 또는 만료 헤더가 없음 = iOS6 Safari가 캐시합니다.
  • Cache-Control max-age=0 및 즉시 만료 = iOS6 Safari가 캐시됩니다.
  • 캐시 제어: 캐시 없음 = iOS6 Safari가 캐시되지 않음

POST에 관한 섹션9.5의 HTTP 사양에서 Apple이 이것을 이용하고 있는 것이 아닌가 생각합니다.

이 메서드에 대한 응답은 적절한 Cache-Control 헤더필드 또는 Expires 헤더필드가 포함되지 않는 한 캐시할 수 없습니다.그러나 303(기타 참조) 응답을 사용하여 캐시 가능한 리소스를 가져오도록 사용자 에이전트에 지시할 수 있습니다.

따라서 이론상으로는 POST 응답을 캐싱할 수 있습니다.누가 알았겠어요?하지만 지금까지 어떤 브라우저 메이커도 그것이 좋은 생각이라고 생각하지 않았다.단, Cache-Control 헤더 또는 Expires 헤더가 설정되어 있지 않은 경우에는 캐싱이 고려되지 않습니다.일부 설정이 되어 있는 경우에만 해당됩니다.그럼 벌레인가 보군

API 전체를 대상으로 하는 Apache 설정의 오른쪽 비트를 다음에 나타냅니다.이는 실제로 아무것도 캐시하고 싶지 않기 때문입니다.POST 전용으로 설정하는 방법은 모르겠습니다.

Header set Cache-Control "no-cache" 

업데이트: POST가 같을 때만 지적하지 않았으므로 POST 데이터 또는 URL 중 하나를 변경하면 문제 없습니다.따라서 다른 곳에서 언급했듯이 URL에 랜덤 데이터 또는 POST 데이터 일부를 추가할 수 있습니다.

업데이트: Apache에서 다음과 같이 원하는 경우 “캐시 없음”을 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 매개 변수 추가
  • 추가, 응답 헤더에 [sno-cache] 추가
  • 추가, 응답 헤더에 [cache-control: no-cache]

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

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

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

위의 솔루션을 사용하는 경우 global:로 설정된 $.ajax() 호출은 $.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()다음과 같은 방법으로 합니다.

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

이걸 알아내느라 몇 시간 허비했어이 캐싱 문제를 개발자에게 알렸으면 좋았을 텐데.




ASP에서 데이터를 가져오는 webapp에서도 같은 문제가 있었습니다.NET 웹 서비스

이 방법은 효과가 있었습니다.

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