javascript आईओएस 6 पर कैशरी $ कैशिंग $.ajax परिणाम है?




jquery caching (20)

आईओएस 6 में अपग्रेड होने के बाद से, हम सफारी के वेब व्यू को $.ajax कॉल कैशिंग की स्वतंत्रता लेते हैं। यह एक फोनगैप एप्लिकेशन के संदर्भ में है, इसलिए यह सफारी वेबव्यू का उपयोग कर रहा है। हमारी $.ajax कॉल POST विधियां हैं और हमारे पास कैश सेट है {cache:false} , लेकिन फिर भी यह हो रहा है। हमने हेडर पर TimeStamp मैन्युअल रूप से जोड़ने का प्रयास किया लेकिन इससे मदद नहीं मिली।

हमने और अधिक शोध किया और पाया कि सफारी केवल उन वेब सेवाओं के लिए कैश किए गए परिणाम लौटा रही है जिनमें फ़ंक्शन हस्ताक्षर है जो स्थिर है और कॉल से कॉल में नहीं बदलता है। उदाहरण के लिए, किसी फ़ंक्शन की कल्पना करें जैसे कुछ:

getNewRecordID(intRecordType)

इस फ़ंक्शन को बार-बार एक ही इनपुट पैरामीटर प्राप्त होते हैं, लेकिन यह डेटा हर बार अलग होना चाहिए।

आईओएस 6 ज़िप को प्रभावशाली ढंग से बनाने के लिए ऐप्पल के जल्दबाजी में होना चाहिए, वे कैश सेटिंग्स से बहुत खुश हैं। क्या किसी और ने आईओएस 6 पर यह व्यवहार देखा है? यदि हां, तो इसका क्या कारण है?

हमने जो कामकाज पाया वह इस तरह कुछ होने के लिए फ़ंक्शन हस्ताक्षर को संशोधित करना था:

getNewRecordID(intRecordType, strTimestamp)

और फिर हमेशा एक TimeStamp पैरामीटर में भी पास करें, और सर्वर पक्ष पर उस मान को छोड़ दें। यह इस मुद्दे के आसपास काम करता है। मुझे उम्मीद है कि यह किसी अन्य गरीब आत्मा की मदद करता है जो इस मुद्दे पर 15 घंटे खर्च करता है जैसा मैंने किया था!


मैं इस तरह कुछ होने के लिए फ़ंक्शन हस्ताक्षर को संशोधित करने के लिए एक समाधान का सुझाव देता हूं:

getNewRecordID (intRecordType, strTimestamp) प्राप्त करें और फिर हमेशा टाइमस्टैंप पैरामीटर में भी पास करें, और सर्वर पक्ष पर उस मान को छोड़ दें। यह इस मुद्दे के आसपास काम करता है।


अनुरोध को अलग करने के लिए कैश-बस्टर पैरामीटर जोड़ते समय एक ठोस समाधान की तरह लगता है, मैं इसके खिलाफ सलाह दूंगा, क्योंकि यह वास्तविक कैशिंग होने पर निर्भर किसी भी एप्लिकेशन को चोट पहुंचाएगा। एपीआई आउटपुट को सही हेडर बनाना सबसे अच्छा संभव समाधान है, भले ही कॉलर्स को कैश बस्टर्स जोड़ने से थोड़ा मुश्किल हो।


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

}

आईपैड 4 / आईओएस 6 के साथ मेरे लिए काम नहीं करने वाली चीजें 6:

मेरा अनुरोध है: कैश-कंट्रोल: नो-कैश

//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);

मुझे PhoneGap एप्लिकेशन में भी यह समस्या थी। मैंने जावास्क्रिप्ट फ़ंक्शन getTime() को निम्न तरीके से उपयोग करके हल किया:

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

मैंने इसे समझने में कुछ घंटे बर्बाद कर दिए। इस कैशिंग मुद्दे के डेवलपर्स को सूचित करने के लिए ऐप्पल का अच्छा लगा होगा।


जबकि मेरा लॉगिन और साइनअप पेज फ़ायरफ़ॉक्स, आईई और क्रोम में एक आकर्षण की तरह काम करता है ... मैं कुछ महीने पहले सफारी में आईओएस और ओएसएक्स के लिए इस मुद्दे से जूझ रहा हूं, मुझे एसओ पर एक कामकाज मिला।

<body onunload="">

या जावास्क्रिप्ट के माध्यम से

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

यह थोड़ी बदसूरत चीज है लेकिन थोड़ी देर के लिए काम करती है।

मुझे नहीं पता क्यों, लेकिन onunload घटना में शून्य वापस लौटना पृष्ठ को सफारी में कैश नहीं किया जाता है।


अपने सभी वेब सेवा अनुरोधों के लिए सरल समाधान, मानते हुए कि आप 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()
    }));
});

here jQuery प्रीफिल्टर कॉल के बारे में और पढ़ें।

यदि आप jQuery का उपयोग नहीं कर रहे हैं, तो अपनी पसंद की लाइब्रेरी के लिए दस्तावेज़ देखें। उनके पास समान कार्यक्षमता हो सकती है।


यह जावास्क्रिप्ट स्निपेट jQuery और jQuery मोबाइल के साथ बढ़िया काम करता है:

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

बस इसे अपने जावास्क्रिप्ट कोड में रखें (jQuery लोड होने के बाद, और AJAX अनुरोध करने से पहले सबसे अच्छा) और इसे मदद करनी चाहिए।


यह केवल pragma:no-cache में pragma:no-cache हेडर जोड़ने के बाद ASP.NET साथ काम किया। Cache-Control: no-cache पर्याप्त नहीं था।


मुझे एक कामकाज मिला जो मुझे उत्सुक बनाता है कि यह क्यों काम करता है। एएसपी.नेट वेब सेवा से संबंधित टेडेज के जवाब को पढ़ने से पहले, मैं काम करने वाले कुछ के साथ आने की कोशिश कर रहा था।

और मैं यह नहीं कह रहा हूं कि यह एक अच्छा समाधान है, लेकिन मैं इसे यहां दस्तावेज करना चाहता था।

मुख्य पृष्ठ: एक जावास्क्रिप्ट फ़ंक्शन, चेकस्टैटस () शामिल है। विधि HTML सामग्री को अद्यतन करने के लिए एक jQuery विधि AJAX कॉल का उपयोग करने वाली एक और विधि को कॉल करती है। मैंने चेकस्टैटस () को कॉल करने के लिए setInterval का उपयोग किया। बेशक, मैं कैशिंग समस्या में भाग गया।

समाधान: अद्यतन को कॉल करने के लिए किसी अन्य पृष्ठ का उपयोग करें।

मुख्य पृष्ठ पर, मैंने एक बुलियन वैरिएबल सेट किया, रनअपडेट, और बॉडी टैग में निम्नलिखित जोड़ा:

<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>

इसलिए, यदि मुख्य पृष्ठ से चेकस्टैटस () को कॉल किया जाता है, तो मुझे कैश की गई सामग्री मिलती है। अगर मैं बाल पृष्ठ से चेकस्टैटस को कॉल करता हूं, तो मुझे अपडेट की गई सामग्री मिलती है।


मुझे आशा है कि यह इस पर दीवार के खिलाफ अपने सिर को टक्कर मारने वाले अन्य डेवलपर्स के लिए उपयोग किया जा सकता है। मैंने पाया कि निम्न में से कोई भी आईओएस 6 पर पोस्टरी प्रतिक्रिया को कैश करने से सफारी को रोकता है:

  • अनुरोध हेडर में [कैश-कंट्रोल: नो-कैश] जोड़ना
  • एक वर्तमान यूआरएल पैरामीटर जैसे वर्तमान समय जोड़ना
  • प्रतिक्रिया शीर्षकों में [प्रज्ञा: नो-कैश] जोड़ना
  • प्रतिक्रिया शीर्षकों में [कैश-कंट्रोल: नो-कैश] जोड़ना

मेरा समाधान मेरे जावास्क्रिप्ट में निम्नलिखित था (मेरे सभी AJAX अनुरोध पोस्ट हैं)।

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

मैं अपने कई सर्वर प्रतिक्रियाओं में [pragma: no-cache] शीर्षलेख भी जोड़ता हूं।

यदि आप उपर्युक्त समाधान का उपयोग करते हैं तो ध्यान रखें कि आपके द्वारा किए गए किसी भी $ .ajax () कॉल को वैश्विक पर सेट किया गया है: झूठी $ .ajaxSetup () में निर्दिष्ट सेटिंग्स का उपयोग नहीं करेगा, इसलिए आपको हेडर को फिर से जोड़ना होगा।


कुछ जांच के बाद, पता चला है कि आईओएस 6 पर सफारी POST को कैश करेगा जिसमें या तो कैश-कंट्रोल हेडर या "कैश-कंट्रोल: अधिकतम-आयु = 0" भी नहीं है।

सेवा कैश के अंत में यादृच्छिक क्वेरीस्ट्रिंग को हैक करने की बजाय वैश्विक स्तर पर होने से रोकने के लिए एकमात्र तरीका यह है कि "कैश-कंट्रोल: नो-कैश" सेट करना है।

इसलिए:

  • कोई कैश-कंट्रोल या हेडर समाप्त नहीं होता है = आईओएस 6 सफारी कैश करेगा
  • कैश-कंट्रोल अधिकतम आयु = 0 और तत्काल समाप्ति = आईओएस 6 सफारी कैश करेगा
  • कैश-कंट्रोल: नो-कैश = आईओएस 6 सफारी कैश नहीं करेगा

मुझे संदेह है कि ऐप्पल पीओएसटी के बारे में धारा 9.5 में HTTP स्पेक से इसका लाभ उठा रहा है:

इस विधि के प्रतिसाद कैश करने योग्य नहीं हैं, जब तक कि प्रतिक्रिया में उपयुक्त कैश-कंट्रोल या हेडर फ़ील्ड समाप्त नहीं हो जाते। हालांकि, 303 (अन्य देखें) प्रतिक्रिया का उपयोग उपयोगकर्ता एजेंट को कैशबल संसाधन पुनर्प्राप्त करने के लिए निर्देशित करने के लिए किया जा सकता है।

तो सिद्धांत में आप पोस्ट प्रतिक्रियाओं को कैश कर सकते हैं ... जो जानता था। लेकिन किसी अन्य ब्राउज़र निर्माता ने कभी सोचा नहीं है कि अब तक यह एक अच्छा विचार होगा। लेकिन जब कैश-कंट्रोल या एक्सपियर हेडर सेट नहीं होते हैं, तो कैशिंग के लिए यह खाता नहीं है, केवल कुछ सेट होने पर ही। तो यह एक बग होना चाहिए।

नीचे मेरे पूरे एपीआई को लक्षित करने के लिए मैं अपने अपाचे कॉन्फ़िगर के दाहिने हिस्से में उपयोग करता हूं क्योंकि ऐसा होता है क्योंकि मैं वास्तव में कुछ भी कैश करना नहीं चाहता हूं, यहां तक ​​कि हो जाता है। मुझे नहीं पता कि यह केवल पोस्ट के लिए कैसे सेट करें।

Header set Cache-Control "no-cache"

अपडेट: बस ध्यान दिया गया कि मैंने यह इंगित नहीं किया कि यह केवल तभी होता है जब POST समान होता है, इसलिए किसी भी पोस्ट डेटा या यूआरएल को बदलें और आप ठीक हैं। तो आप कहीं और उल्लेख कर सकते हैं बस यूआरएल या कुछ POST डेटा में कुछ यादृच्छिक डेटा जोड़ें।

अपडेट करें: यदि आप अपाचे में ऐसा करना चाहते हैं तो आप केवल "पोस्ट-कैश" को POST तक सीमित कर सकते हैं:

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

यह 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();
  }
});

मुझे एएसपी.NET webservice से डेटा प्राप्त करने वाले वेबपैप के साथ एक ही समस्या थी

यह मेरे लिए काम किया:

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

अपने ब्लॉग पोस्ट से आईओएस 6.0 कैशिंग अजाक्स POST अनुरोध :

इसे कैसे ठीक करें: अनुरोधों के कैशिंग को रोकने के लिए कई विधियां हैं। अनुशंसित विधि नो-कैश हेडर जोड़ रही है। इस तरह यह किया जाता है।

jQuery:

आईओएस 6.0 के लिए जांचें और इस तरह अजाक्स हेडर सेट करें:

$.ajaxSetup({ cache: false });

ZeptoJS:

आईओएस 6.0 के लिए जांचें और इस तरह अजाक्स हेडर सेट करें:

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

पीएचपी

header('Cache-Control: no-cache, no-store, must-revalidate'); // HTTP 1.1.
header('Pragma: no-cache'); // HTTP 1.0.

मैं $ .ajaxSetup के संयोजन का उपयोग करके और मेरी पोस्ट के यूआरएल (पोस्ट पैरामीटर / बॉडी के लिए) में टाइमस्टैंप जोड़कर मेरी समस्या को ठीक करने में सक्षम था। यह पिछले उत्तरों की सिफारिशों के आधार पर

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

जीडब्ल्यूटी-आरपीसी के लिए यह काम है

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

मुझे लगता है कि आप पहले से ही अपनी समस्या का समाधान कर चुके हैं, लेकिन मुझे वेब कैशिंग के बारे में एक विचार साझा करने दें।

यह सच है कि आप उपयोग की जाने वाली प्रत्येक भाषा में कई शीर्षलेख जोड़ सकते हैं, सर्वर साइड, क्लाइंट साइड, और आप वेब कैशिंग से बचने के लिए कई अन्य चाल का उपयोग कर सकते हैं, लेकिन हमेशा सोचें कि आप कभी भी यह नहीं जान सकते कि क्लाइंट आपके सर्वर से कनेक्ट हो रहा है, आप कभी नहीं जानते कि क्या वह एक होटल "हॉट-स्पॉट" कनेक्शन का उपयोग कर रहा है जो स्क्विड या अन्य कैशिंग उत्पादों का उपयोग करता है।

यदि उपयोगकर्ता अपनी असली स्थिति, आदि को छिपाने के लिए प्रॉक्सी का उपयोग कर रहे हैं ... कैशिंग से बचने का असली एकमात्र तरीका अनुरोध में टाइमस्टैम्प है, अगर अप्रयुक्त है।

उदाहरण के लिए:

/ajax_helper.php?ts=3211321456

फिर आपको प्राप्त होने वाले प्रत्येक कैश प्रबंधक को कैश रिपोजिटरी में एक ही यूआरएल नहीं मिला और पेज सामग्री को दोबारा डाउनलोड करें।


रुबी के सिनात्रा में

before '*' do
  if env['REQUEST_METHOD'] == 'POST'
    headers 'Cache-Control' => 'no-cache, no-store, must-revalidate'
  end
end

आप Ajax फ़ंक्शन के शीर्ष पर निम्नलिखित ((1.7.1 के रूप में) करके 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 : "");
}




mobile-safari