AngularJS देव मशीन पर आंशिक कैशिंग अक्षम करता है


210

मुझे एंगुलरजेएस में कैशिंग धारावाहिकों के साथ समस्या है।

मेरे HTML पृष्ठ में मेरे पास है:

<body>
 <div ng-view></div>
<body>

जहाँ मेरे भाग भरे हुए हैं।

जब मैं अपने आंशिक में HTML कोड बदलता हूं, तब भी ब्राउज़र पुराने डेटा को लोड करता है।

क्या कोई वर्कअराउंड है?


4
बस एक त्वरित टिप्पणी: मुझे इससे एक समस्या थी जो कि कैश कंट्रोल हेडर से संबंधित थी जो मेरा फ्लास्क एप्लिकेशन वापस भेज रहा था। मुझे app.config.update(SEND_FILE_MAX_AGE_DEFAULT=0)अपने साथ जोड़कर समस्या का समाधान मिल गया flask_app.py। (मुझे लगता है कि इसी तरह की चीजें अन्य वेब सर्वर के लिए मौजूद हैं)।
gatoatigrado

4
यदि आप क्रोम का उपयोग कर रहे हैं, तो बस Ctrl+Shift+R(यानी हार्ड रीलोड) और कोई बात नहीं कि कैशिंग तंत्र का उपयोग किया जाता है क्रोम इसे अनदेखा कर देगा और सभी लिपियों, स्टाइलशीट आदि को फिर से प्राप्त करेगा
snajahi

4
ctrl + shift + R क्रोम में मेरे लिए काम नहीं करता है, लेकिन डेवलपर टूल "नेटवर्क" टैब पर, "अक्षम कैश" पर क्लिक करने से यह पूरी तरह से काम करता है। मेरे लिए, यह एक क्लाइंट साइड समस्या है जिसे सर्वर पर हैक्स का उपयोग करके हल नहीं किया जाना चाहिए जैसे कि नीचे दिए गए कई सुझाव; यह उस क्लाइंट पर तय किया जाना चाहिए जहां "समस्या" मौजूद है। यदि आप इसे सर्वर पर ठीक करते हैं, और इसे ठीक करना भूल जाते हैं, तो उत्पादन पर प्रतिकूल प्रभाव पड़ सकता है।
एंट कुटसेरा

8
ctrl + shift + R सामान्य अनुरोधों के लिए कैश को बायपास करता है। ajax अनुरोधों के लिए कोणीय से बनाया ng-include| ng-view| templateUrlइस शॉर्टकट द्वारा संभाला नहीं जाता है
एंड्रे वेरलैंग

2
साइट पर जाने पर आप सभी अंतिम उपयोगकर्ताओं को Ctrl + Shift + R से नहीं पूछ सकते हैं, इसलिए गैर-विकास मामले के लिए इस प्रश्न का उत्तर क्या है? "मेरे लिए, यह एक क्लाइंट साइड समस्या है जिसे सर्वर पर हैक्स का उपयोग करके हल नहीं किया जाना चाहिए जैसे कि नीचे दिए गए कई सुझाव" - मैं सहमत नहीं हूं, आप ग्राहकों को एक वेब वातावरण में नियंत्रित नहीं कर सकते हैं ताकि उत्पादन के लिए तय हो सके आवेदन चालित होना चाहिए। उस कारण से मैंने स्वीकार किया: $ rootScope। $ On ('$ viewContentLoaded', function () {$ templateCache.removeAll ();});
राबर्ट क्रिश्चियन

जवाबों:


200

विकास के लिए आप ब्राउज़र कैश को भी निष्क्रिय कर सकते हैं - क्रोम देव उपकरण में नीचे दाईं ओर गियर पर क्लिक करें और विकल्प पर टिक करें

कैश को अक्षम करें (जब डेव टूक खुला हो)

अद्यतन: फ़ायरफ़ॉक्स में डिबगर में एक ही विकल्प है -> सेटिंग्स -> उन्नत अनुभाग (संस्करण 33 के लिए जाँच)

अपडेट 2: हालाँकि यह विकल्प फ़ायरफ़ॉक्स में दिखाई देता है लेकिन कुछ रिपोर्ट यह काम नहीं करती है। मेरा सुझाव है कि फायरबग का उपयोग करें और हयातुल्लाह उत्तर का पालन करें।


7
इसे स्वीकृत उत्तर होना चाहिए क्योंकि इसमें कोड परिवर्तन की आवश्यकता नहीं है, और यह ओपी के अनुरोध के बिंदु पर अधिक है। बेशक, आप अनुरोधों को कैश करने के लिए एक उत्पादन ऐप चाहते हैं, इसलिए उपरोक्त लोगों ने जो सुझाव दिया है, उसका अर्थ है कि यदि कोड किसी उत्पादन ऐप में छोड़ दिया गया है तो समस्याग्रस्त साबित हो सकता है।
एरोन वैगनर

फ़ायरफ़ॉक्स जैसे अन्य ब्राउज़रों के लिए कोई सुझाव?
लेवेरेमे

फ़ायरफ़ॉक्स में: डीबगर> सेटिंग्स (गियर) एक ही विकल्प है।
ल्यूकसोलर

5
यह फ़ायरफ़ॉक्स में काम नहीं करता है। जब कैश अक्षम होता है, और टूलबॉक्स खुला होता है, तब भी टेम्प्लेट कैश्ड होते हैं।
पैट्रिक जे कॉलिन्स

4
क्या कैशिंग उत्पादन को भी प्रभावित करता है? क्या होगा अगर मैं सर्वर पर नई वेब फ़ाइलों को धक्का देता हूं, जो उत्पादन ग्राहकों के बाद के अनुरोधों को पूर्व-प्रकाशित कैश्ड संस्करणों को लोड करने से रोकता है?
meffect

111

@ वैलेंटाइन के उत्तर पर थोड़ा सा निर्माण, यहाँ हमेशा कैश को साफ़ करने का एक तरीका है जब भी एनजी-व्यू कंटेंट बदलता है:

myApp.run(function($rootScope, $templateCache) {
   $rootScope.$on('$viewContentLoaded', function() {
      $templateCache.removeAll();
   });
});

@ user252690 संभवतः यह भी सुनिश्चित करने की आवश्यकता है कि HTML टेम्पलेट कैश हेडर के साथ नहीं भेजा गया था। संभावित सुधारों के लिए यहां और यहां देखें
क्रिस फोस्टर

30
थोड़ी चेतावनी: $ टेम्पलेट खाली करना वास्तव में अनपेक्षित परिणाम हो सकता है। उदाहरण के लिए, यूआई बूटस्ट्रैप प्रारंभ के दौरान सीधे डिफ़ॉल्ट रूप से $ खाका में जोड़ता है और बाद में उन्हें वहाँ होने की उम्मीद करता है।
स्ट्रिल

@ स्ट्रील मैं कोणीय-यूआई-बूटस्ट्रैप मोडल का उपयोग करने की कोशिश कर रहा था। पॉप अप दिखाई नहीं दे रहा था। क्योंकि $ templateCache.removeAll (); इसके लिए कोई तय?
मुकुन

4
@Mukun: मेरे द्वारा इसे हटाने के तरीके को हटाने के अलावा और कोई आसान तरीका नहीं है, इसे हटाएं () का उपयोग न करें, बल्कि केवल हटाने के लिए () का उपयोग करें। आपको यह जानने के लिए कि किसी कुंजी को हटाने के लिए किसी प्रकार की बहीखाता पद्धति की आवश्यकता होगी।
स्ट्रिल

क्या विशिष्ट यूआई दृश्य कैश के लिए केवल कैश को साफ़ करने का कोई तरीका है।
गायन

37

जैसा कि अन्य उत्तरों में उल्लेख किया गया है, यहाँ और यहाँ , कैश का उपयोग करके साफ़ किया जा सकता है:

$templateCache.removeAll();

हालांकि टिप्पणी में gatoatigrado द्वारा सुझाए गए अनुसार , यह केवल तभी काम करता है जब html टेम्पलेट बिना किसी कैश हेडर के परोसा गया हो।

तो यह मेरे लिए काम करता है:

कोणीय में:

app.run(['$templateCache', function ( $templateCache ) {
    $templateCache.removeAll(); }]);

आप कई तरीकों से कैश हेडर जोड़ रहे होंगे, लेकिन यहां कुछ समाधान हैं जो मेरे लिए काम करते हैं।

यदि उपयोग कर रहे हैं IIS, तो इसे अपने web.config में जोड़ें:

<location path="scripts/app/views">
  <system.webServer>
    <staticContent>
      <clientCache cacheControlMode="DisableCache" />
    </staticContent>
  </system.webServer>
</location>

यदि Nginx का उपयोग कर रहे हैं, तो आप इसे अपने विन्यास में जोड़ सकते हैं:

location ^~ /scripts/app/views/ {
    expires -1;   
}

संपादित करें

मुझे बस एहसास हुआ कि प्रश्न devमशीन का उल्लेख करता है लेकिन उम्मीद है कि यह अभी भी किसी की मदद कर सकता है ...


2
हां, भले ही यह मूल प्रश्न का उत्तर नहीं देता है, लेकिन इससे मुझे वास्तव में एक लाइव वेबसाइट पर कैशिंग मुद्दे को हल करने में मदद मिली।
आंद्रे

31

यदि आप कैश के बारे में बात कर रहे हैं जो पूरे पृष्ठ को फिर से लोड किए बिना टेम्पलेट्स के कैशिंग के लिए उपयोग किया जाता है, तो आप इसे कुछ इस तरह से खाली कर सकते हैं:

.controller('mainCtrl', function($scope, $templateCache) {
  $scope.clearCache = function() { 
    $templateCache.removeAll();
  }
});

और मार्कअप में:

<button ng-click='clearCache()'>Clear cache</button>

और कैश को साफ़ करने के लिए इस बटन को दबाएं।


22

फायरबग (22.0.6) का उपयोग करके फ़ायरफ़ॉक्स (33.1.1) के लिए समाधान

  1. उपकरण> वेब-उपकरण> फायरबग> फायरबग खोलें।
  2. फायरबग विचारों में "नेट" दृश्य पर जाएं।
  3. एक ड्रॉप डाउन मेनू प्रतीक "नेट" (दृश्य का शीर्षक) के बगल में दिखाई देगा।
  4. ड्रॉप डाउन मेनू से "ब्राउज़र कैश अक्षम करें" चुनें।

मैक पर फायरबग (2.0.11) और फ़ायरफ़ॉक्स (38.0.1) पर कोशिश की लेकिन यह काम नहीं किया।
पौल

19

इस स्निपेट ने मुझे टेम्पलेट कैशिंग से छुटकारा पाने में मदद की

app.run(function($rootScope, $templateCache) {
    $rootScope.$on('$routeChangeStart', function(event, next, current) {
        if (typeof(current) !== 'undefined'){
            $templateCache.remove(current.templateUrl);
        }
    });
});

निम्नलिखित स्निपेट के विवरण इस लिंक पर देखे जा सकते हैं: http://oncodesign.io/2014/02/19/safely-prevent-template-caching-in-angularjs/


नाइटपिक लेकिन जब वर्तमान कभी एक वस्तु नहीं है? सुनिश्चित नहीं हैं कि यह कभी नहीं या तो है, लेकिनif (!current) { return; }
नैट-विल्किंस

यह मार्ग-आधारित टेम्प्लेट्स के कोणीय के कैशिंग को हरा देता है, लेकिन एनजी-शामिल नहीं करता है।
bradw2k

16

मैं इसे केवल सभी संभावनाओं को कवर करने के लिए पोस्ट कर रहा हूं क्योंकि दोनों में से किसी भी अन्य समाधान ने मेरे लिए काम नहीं किया (वे कोणीय-बूटस्ट्रैप टेम्पलेट निर्भरता के कारण त्रुटियों को फेंक दिया, दूसरों के बीच)।

जब आप किसी विशेष टेम्पलेट को विकसित / डिबग कर रहे हैं, तो आप इस तरह से पथ में टाइमस्टैम्प को शामिल करके हमेशा इसे ताज़ा कर सकते हैं:

       $modal.open({
          // TODO: Only while dev/debug. Remove later.
          templateUrl: 'core/admin/organizations/modal-selector/modal-selector.html?nd=' + Date.now(),
          controller : function ($scope, $modalInstance) {
            $scope.ok = function () {
              $modalInstance.close();
            };
          }
        });

चर ?nd=' + Date.now()में अंतिम नोट करें templateUrl


1
बाद में आप .value('DEBUG', true)उस लाइन को सक्षम करने के लिए सेट कर सकते हैं या नहीं।
डायोसनी

1
मेरा समाधान निम्नलिखित के तहत मेरे मुख्य मॉड्यूल के आरंभीकरण चरण के .run(function($rootScope) { $rootScope.DEBUG = true; ...भीतर और फिर निर्देश के भीतर $ rootScope जैसे .directive('filter', ['$rootScope', function($rootScope)...और लौटे हुए ऑब्जेक्ट-प्रॉपर्टी में इंजेक्शन का उपयोग करना था templateUrl: '/app/components/filter/filter-template.html' + ($rootScope.DEBUG ? '?n=' + Date.now() : ''):। हो सकता है कि आप अपने .value ('DEBUG', सच) दृष्टिकोण को विस्तृत कर सकें? Upvoted!
जैकलाइमरडेउर

का उपयोग .value('DEBUG', trueउसी तरह से है जैसा आपने किया था $rootScope, लेकिन इसे बंद किए बिना :) आप बाद DEBUGमें नियंत्रक और क्वेरी में एक सामान्य सेवा के रूप में इंजेक्ट कर सकते थे ।
डायोसनी

.value(...)यदि आप बहुत अधिक परिष्कृत नहीं हैं, तो क्या आप अपने उत्तर में सोर्सकोड का विस्तार कर सकते हैं । मुझे लगता है कि अवधारणा मेरे पीछे एक कोणीय अभ्यास है जो मेरे लिए अज्ञात है।
जैकलाइमरडे

1
आयनिक के साथ काम करते समय यह समाधान बहुत उपयोगी है। यह मुझे इतना समय बचाने वाला है क्योंकि यह लिवरेलड को फिर से उपयोगी बनाता है। अनेक अनेक धन्यवाद!
अजूसर

11

जैसा कि दूसरों ने कहा है, देव उद्देश्यों के लिए कैशिंग को पूरी तरह से बदलना कोड को बदले बिना आसानी से किया जा सकता है: ब्राउज़र सेटिंग या प्लगइन का उपयोग करें। देव के बाहर, मार्ग-आधारित टेम्प्लेट के कोणीय टेम्पलेट को पराजित करने के लिए, Shayan के रूप में दिखाए गए मार्ग UI रूट के लिए $ मार्ग परिवर्तन (या $ StateChangeStart, के लिए) के दौरान टेम्पलेट URL को कैश से हटा दें। हालाँकि, यह एनजी-द्वारा लोड किए गए टेम्प्लेट के कैशिंग को प्रभावित नहीं करता है, क्योंकि उन टेम्प्लेट को राउटर के माध्यम से लोड नहीं किया जाता है।

मैं किसी भी टेम्पलेट को हॉटफ़िक्स करने में सक्षम होना चाहता था, जिसमें एनजी-लोड द्वारा लोड किए गए, उत्पादन में शामिल हैं और उपयोगकर्ताओं को पूरे ब्राउज़र को पुनः लोड किए बिना, जल्दी से अपने ब्राउज़र में हॉटफ़िक्स प्राप्त करना है। मैं खाका के लिए HTTP कैशिंग को हराने के बारे में चिंतित नहीं हूं। समाधान हर HTTP अनुरोध को रोकना है जो ऐप बनाता है, उन लोगों को अनदेखा करें जो मेरे ऐप के .html टेम्प्लेट के लिए नहीं हैं, फिर टेम्पलेट के URL में एक परम जोड़ें जो हर मिनट बदलता है। ध्यान दें कि पथ-जांच आपके ऐप के टेम्प्लेट के पथ के लिए विशिष्ट है। एक अलग अंतराल प्राप्त करने के लिए, परम के लिए गणित बदलें, या कोई कैशिंग प्राप्त करने के लिए% को पूरी तरह से हटा दें।

// this defeats Angular's $templateCache on a 1-minute interval
// as a side-effect it also defeats HTTP (browser) caching
angular.module('myApp').config(function($httpProvider, ...) {
    $httpProvider.interceptors.push(function() {
        return {
            'request': function(config) {
                config.url = getTimeVersionedUrl(config.url);
                return config;
            }
        };
    });

    function getTimeVersionedUrl(url) {
        // only do for html templates of this app
        // NOTE: the path to test for is app dependent!
        if (!url || url.indexOf('a/app/') < 0 || url.indexOf('.html') < 0) return url;
        // create a URL param that changes every minute
        // and add it intelligently to the template's previous url
        var param = 'v=' + ~~(Date.now() / 60000) % 10000; // 4 unique digits every minute
        if (url.indexOf('?') > 0) {
            if (url.indexOf('v=') > 0) return url.replace(/v=[0-9](4)/, param);
            return url + '&' + param;
        }
        return url + '?' + param;
    }

मुझे आपके समाधान में दिलचस्पी है - क्या आप बदलाव करने के बाद इस कोड को अच्छे के लिए रखते हैं - या एक निश्चित अवधि के लिए? कारण - प्रदर्शन को लेकर चिंतित होंगे। इसके अलावा, आप HTTP को पराजित करने वाले साइड-इफ़ेक्ट का उल्लेख करते हैं। आपका मतलब है कि एक अच्छा साइड-इफेक्ट तरीका सही है - इसका मतलब है कि 'हॉटफिक्स' के लिए आप क्या चाहते हैं? Thx
jamie

1
मैं इस कोड को अच्छे के लिए छोड़ देता हूं, हालांकि हमने कैश-बस्टिंग की लंबाई को 10 मिनट तक वापस डायल किया। इसलिए प्रत्येक 10 मिनट के उपयोग में, एक उपयोगकर्ता ताज़ा html टेम्पलेट पुनः लोड कर रहा होगा। मेरे बिज़ ऐप के लिए जो हॉट-पैच टेम्प्लेट की क्षमता हासिल करने के लिए एक स्वीकार्य लागत है, लेकिन जाहिर है कि यह कुछ प्रकार के ऐप के लिए प्रदर्शन को बहुत कम कर देगा। ... यह दुर्भाग्यपूर्ण है कि HTTP कैशिंग को भी हराया गया है, लेकिन मुझे एताग आदि को हराए बिना कोणीय टेम्प्लेट कैशिंग को समझदारी से हराने का तरीका नहीं दिखता है। IMO कोणीय टेम्प्लेट कैशिंग केवल पर्याप्त रूप से कॉन्फ़िगर करने योग्य नहीं है।
bradw2k

1
+1 मेरे पास एक ही विचार था, लेकिन मैं केवल लोकलहोस्ट के लिए इंटरसेप्ट करता हूं। आप इंटरसेप्टर के मेरे कार्यान्वयन को यहाँ देख सकते हैं: overengineer.net/…
joshcomley

@joshcomley यदि आपको केवल लोकलहोस्ट पर कैशिंग को हराने की आवश्यकता है, तो सभी कैशिंग को हराने वाले ब्राउज़र प्लगइन का उपयोग क्यों न करें?
bradw2k

@ bradw2k इस तरह से मैं पूर्ण नियंत्रण में हूं कि क्या है और कैश नहीं है, जो विकास के लिए उपयोगी हो सकता है। मैं सभी ब्राउज़रों में भी परीक्षण करता हूं, और सभी ब्राउज़रों में एक्सटेंशन नहीं होते हैं जो मुझे चाहिए। मेरे पास विकास में साइट पर एक संकेतक भी हो सकता है जो मुझे बता रहा है कि कैशिंग अक्षम है या नहीं, क्योंकि कभी-कभी मैं केवल थोड़ी देर के लिए ब्राउज़र में अक्षम करना और परीक्षण करना चाहता हूं।
२०:२४ पर जोशमॉले

8

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

function configureTemplateFactory($provide) {
    // Set a suffix outside the decorator function 
    var cacheBust = Date.now().toString();

    function templateFactoryDecorator($delegate) {
        var fromUrl = angular.bind($delegate, $delegate.fromUrl);
        $delegate.fromUrl = function (url, params) {
            if (url !== null && angular.isDefined(url) && angular.isString(url)) {
                url += (url.indexOf("?") === -1 ? "?" : "&");
                url += "v=" + cacheBust;
            }

            return fromUrl(url, params);
        };

        return $delegate;
    }

    $provide.decorator('$templateFactory', ['$delegate', templateFactoryDecorator]);
}

app.config(['$provide', configureTemplateFactory]);

मुझे यकीन है कि आप $ मार्गप्रोपाइडर में "जब" विधि को सजाने के द्वारा एक ही परिणाम प्राप्त कर सकते हैं।


एक बेहतर विकल्प $ टेम्पलेट में कोणीय js टेम्प्लेट को पंजीकृत करने के लिए gulp- कोणीय-टेम्पलेटकैश जैसे प्लगइन का उपयोग करना है। इसका उपयोग गुल-रेव के साथ किया जाना चाहिए। हर बार जब कोई टेम्प्लेट बदलता है, तो एक नया जावास्क्रिप्ट फ़ाइल एक अलग संशोधन संख्या के साथ बनाया जाएगा और कैशिंग एक मुद्दा कभी नहीं होगा।
अमन महाजन

3

मैंने पाया कि HTTP इंटरसेप्टर विधि बहुत अच्छी तरह से काम करती है, और अतिरिक्त लचीलापन और नियंत्रण की अनुमति देती है। इसके अतिरिक्त, आप बस्टर वैरिएबल के रूप में रिलीज़ हैश का उपयोग करके प्रत्येक उत्पादन रिलीज़ के लिए कैश-बस्ट कर सकते हैं।

यहाँ देव कैशबस्टिंग विधि का उपयोग करने जैसा दिखता है Date

app.factory('cachebustInjector', function(conf) {   
    var cachebustInjector = {
        request: function(config) {    
            // new timestamp will be appended to each new partial .html request to prevent caching in a dev environment               
            var buster = new Date().getTime();

            if (config.url.indexOf('static/angular_templates') > -1) {
                config.url += ['?v=', buster].join('');
            }
            return config;
        }
    };
    return cachebustInjector;
});

app.config(['$httpProvider', function($httpProvider) {
    $httpProvider.interceptors.push('cachebustInjector');
}]);

1

यहां क्रोम में एक और विकल्प है।

F12डेवलपर उपकरण खोलने के लिए मारो । फिर संसाधन > कैश संग्रहण > कैश रीफ़्रेश करें

यहां छवि विवरण दर्ज करें

मुझे यह विकल्प पसंद है क्योंकि मुझे कैश को अन्य उत्तरों की तरह अक्षम नहीं करना है।


नवंबर 2016 में Chrome v। 54.0.2840.99 में मैंने इसे एक टैब पर पाया, जिसे संसाधन से अधिक Application.rather कहा जाता है।
स्टैकऑवरफ्लोवर

0

ब्राउज़र / प्रॉक्सी कैशिंग को रोकने के लिए कोई समाधान नहीं है क्योंकि आपके पास इस पर नियंत्रण नहीं हो सकता है।

अपने उपयोगकर्ताओं को HTML फ़ाइल का नाम बदलने के लिए नई सामग्री को बाध्य करने का दूसरा तरीका! बिल्कुल वैसे ही जैसे https://www.npmjs.com/package/grunt-filerev एसेट्स के लिए करता है।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.