source

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

factcode 2022. 9. 28. 00:05
반응형

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

6로의 Safari의 웹는 iOS 6을 수 .$.ajaxPhoneGap은 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);
    ...
}

드디어 업로드 문제를 해결할 수 있게 되었습니다.

JavaScript의 경우:

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

PHP의 경우:

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

Ajax POST 요청을 캐싱하는 iOS 6.0 블로그 투고:

수정 방법:요청 캐싱을 방지하는 방법은 다양합니다.권장되는 방법은 캐시 없음 헤더를 추가하는 것입니다.이렇게 하는 거예요.

j쿼리:

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.

이 JavaScript 스니펫은 jQuery 및 jQuery Mobile에서 잘 작동합니다.

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

jQuery가 로드된 후 및 AJAX 요청을 수행하기 전에 JavaScript 코드의 어딘가에 두면 도움이 됩니다.

또한 다음(1.7.1 기준)을 수행하여 Ajax 함수 위에 jQuery Ajax 함수를 수정하여 이 문제를 해결할 수 있습니다(7212줄부터 함수가 시작됩니다).이 변경으로 모든 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 : "");
}

GWT-RPC 서비스의 간단한 회피책은 모든 리모트 메서드에 이를 추가하는 것입니다.

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

바즈1nga의 경우★★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();
  }
});

홈 화면에 추가된 웹 앱에 대한 이 문제를 해결하려면 상위 두 가지 해결 방법을 모두 따라야 합니다.새로운 요구가 앞으로 캐시되지 않도록 하려면 웹 서버에서 캐싱을 해제해야 합니다.또한 이미 캐시된 요구를 처리하기 위해서는 모든 포스트 요구에 랜덤 입력을 추가해야 합니다.제 투고를 참조해 주세요.

iOS6 - 홈 화면에 추가된 웹 앱의 캐시된 Ajax POST 요청을 클리어하는 방법이 있습니까?

경고: 서버의 캐시를 끄지 않고 요청에 타임스탬프를 추가하여 회피책을 구현한 모든 사용자에게 적용됩니다.앱이 홈 화면에 추가되면 Every Post Response가 캐시되고 Safari 캐시를 클리어해도 지워지지 않으며 만료되지 않습니다.누군가 그것을 지울 방법이 없다면, 이것은 잠재적인 메모리 유출처럼 보인다!

iPad 4/iOS 6에서는 작동하지 않았던 것:

요청 내용: Cache-Control: no-cache

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

캐시 추가: jQuery ajax 호출에 오류가 있음

 $.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);

이것이 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);    

ASP에서의 회피책입니다.NET(패지메트, 웹 서비스 등)

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

캐시 버스터 파라미터를 추가하여 요구가 다른 것처럼 보이도록 하는 것은 확실한 솔루션인 것처럼 보이지만, 실제 캐시에 의존하는 어플리케이션은 모두 피해를 입게 되므로 이 파라미터는 사용하지 않는 것이 좋습니다.발신자에 캐시 버스터를 추가하는 것보다 조금 어렵더라도 API 출력을 올바르게 하는 것이 최선의 해결책입니다.

「 」를 위해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.comm.struts.struts.필터가 포함되어 있습니다.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() {
    }

}

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

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

사용하는 각 언어(서버 측, 클라이언트 측)로 많은 헤더를 추가할 수 있습니다.또한 웹 캐싱을 피하기 위해 다른 많은 방법을 사용할 수 있습니다.그러나 클라이언트가 서버에 접속하고 있는 장소를 알 수 없고, Squid 또는 기타 캐싱 제품을 사용하는 호텔 "핫스팟" 연결을 사용하고 있는지 알 수 없습니다.

사용자가 프록시를 사용하여 실제 위치를 숨기는 등 캐시를 회피하는 유일한 방법은 요청 내 타임스탬프(사용하지 않는 경우)입니다.

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

/ajax_helper.php?ts=3211321456

그럼어에 통과하는 것마다 캐시 매니저는 캐시 리포지토리에 re-download 페이지 콘텐츠 그 같은 URL을 찾는다.

앱에 따라 지금 iOS6에서 Safari&gt를 사용하여 문제를 쏘다;를 괴롭힐 수 있다.Advanced>.웹 검열관은 이를 상황에 도움이 된다.

사파리에 맥에 대한 그 골치 거리 개발자 메뉴를 사용하려면 앱 웹 로봇이 전화 연결합니다.

아이 폰 업데이트 후 앱 웹기 보기를 사용하는 방법으로 특정한 등의 웹 사이트 데이터 iOS6.오직 한 앱, 이 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 콜

왜 효과가 있는지 궁금해지는 해결 방법이 하나 있습니다.ASP에 관한 Tadej의 답변을 읽기 전에.NET 웹 서비스, 저는 뭔가 효과가 있는 것을 생각해 내고 있었습니다.

이 솔루션이 좋은 솔루션이라고는 할 수 없지만, 여기서 문서화하려고 합니다.

메인 페이지: JavaScript 함수 checkStatus()가 포함되어 있습니다.이 메서드는 jQuery AJAX 호출을 사용하여 html 콘텐츠를 업데이트하는 다른 메서드를 호출합니다.setInterval을 사용하여 checkStatus()를 호출했습니다.물론 캐싱 문제에 부딪혔죠.

해결책: 다른 페이지를 사용하여 업데이트를 호출합니다.

메인 페이지에서 부울 변수 runUpdate를 설정하고 본문 태그에 다음을 추가했습니다.

<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를 호출하면 업데이트된 내용이 나타납니다.

Firefox, IE, Chrome에서는 로그인 페이지와 등록 페이지가 매력적으로 기능하지만...Safari for IOS 및 OSX에서 이 문제를 해결하기 위해 노력하고 있습니다.몇 달 전에 SO에 대한 회피책을 찾았습니다.

<body onunload="">

또는 javascript를 통한

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

이건 좀 못생겼지만 한동안은 효과가 있어요.

그런지 to to null null null null null null null null null null null null null null null null null null null null null 로 onunload【사파리.

iOS 버전 9와 10을 실행하는 구형 iPhone과 iPad는 Apple의 CPU 속도 저하로 인해 빈 AJAX 결과를 반환하는 경우가 있습니다.빈 결과를 반환할 때 iOS는 캐시에서 결과를 반환하는 것처럼 서버를 호출하지 않습니다.빈도는 AJAX 콜의 약 10~30%에서 빈칸으로 반환되는 빈도는 공백입니다.

그 해결책은 믿기 어렵다.1분만 기다렸다가 다시 전화하세요.테스트에서는 1회만 반복하면 되는데, 최대 4회까지 호출할 수 있는 코드를 작성했습니다.1초 대기 시간이 필요한지는 잘 모르겠지만, 반복적인 호출로 인해 서버에 부담을 주는 위험을 감수하고 싶지 않았습니다.

다른 데이터를 가진 다른 API 파일을 호출하는 두 개의 다른 AJAX 호출에서 문제가 발생했음을 발견했습니다.하지만 어떤 AJAX 통화에서도 일어날 수 있는 일이라 걱정입니다.모든 AJAX 결과를 검사하지 않고 오래된 디바이스에서 모든 콜을 여러 번 테스트하지 않기 때문에 알 수 없습니다.

AJAX 호출이 사용하던 문제: POST, 비동기 = true, setRequest헤더 =('Content-Type', 'application/x-www-form-urlencoded')

문제가 발생하면 보통 AJAX 콜이1개만 진행됩니다AJAX 콜이 중복되어서가 아닙니다.기기가 사용 중일 때도 있고 그렇지 않을 때도 있습니다. DevTools가 없으면 당시 무슨 일이 일어나고 있는지 알 수 없습니다.

iOS 13은 크롬이나 파이어폭스를 지원하지 않습니다.iOS 11 또는 12를 실행하는 테스트 장치는 없습니다.다른 사람이 시험해 볼 수 있지 않을까?

이 문제를 검색할 때 이 질문이 Google 검색 결과 중 가장 높은 항목이기 때문에 이 점에 유의합니다.

ASP에서 작동했습니다.NET을 추가한 후에만pragma:no-cacheIIS의 헤더입니다. Cache-Control: no-cache충분하지 않았습니다.

함수 시그니처를 다음과 같이 변경하는 회피책을 권장합니다.

새로운 레코드를 취득하다ID(intRecordType, strTimestamp)를 지정한 후 항상 TimeStamp 파라미터도 전달하고 서버 측에서 해당 값을 폐기합니다.이 문제는 회피할 수 있습니다.

언급URL : https://stackoverflow.com/questions/12506897/is-safari-on-ios-6-caching-ajax-results

반응형