कुछ छवियों के लिए कैश अक्षम करें


113

मैं एक PHP lib का उपयोग करके कुछ छवियां उत्पन्न करता हूं।

कभी-कभी ब्राउज़र नई उत्पन्न फ़ाइल को लोड नहीं करता है।

मेरे द्वारा गतिशील रूप से बनाई गई छवियों के लिए मैं कैश को कैसे निष्क्रिय कर सकता हूं?

नोट: मुझे समय के साथ बनाई गई छवियों के लिए एक ही नाम का उपयोग करना होगा।

जवाबों:


233

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

इसलिए, उदाहरण के लिए -

<img src="image.png" />

बन जाएगा

<img src="image.png?dummy=8484744" />

या

<img src="image.png?dummy=371662" />

वेब-सर्वर के दृष्टिकोण से एक ही फ़ाइल एक्सेस की जाती है, लेकिन ब्राउज़र के दृष्टिकोण से कोई कैशिंग प्रदर्शन नहीं किया जा सकता है।

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

आपको यह सत्यापित करने की आवश्यकता होगी कि आपका वेब-सर्वर इस ट्रिक का सामना कर सकता है या नहीं।


87
यादृच्छिक संख्याओं के बजाय, टाइमस्टैम्प का उपयोग करें जो डेटा बदल गया है या प्रतिबिंबित डेटा का एक संस्करण संख्या है।
19


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

मेरा मानना ​​है कि यह लेख इस तरह के व्यवहार का कारण बताता है।
मेटलकोडर

1
यह वास्तव में काम नहीं करता है, छवि को दूसरे तरीके से फ्लश करने की आवश्यकता है (आमतौर पर छवि फसल पर, छवि समान रहती है)
बेन

44

ब्राउज़र कैशिंग रणनीतियों को HTTP हेडर द्वारा नियंत्रित किया जा सकता है। याद रखें कि वे सिर्फ एक संकेत हैं, वास्तव में। चूंकि ब्राउज़र इस (और किसी भी) क्षेत्र में बहुत असंगत हैं, इसलिए आपको ब्राउज़रों की एक सीमा पर वांछित प्रभाव प्राप्त करने के लिए कई हेडर की आवश्यकता होगी।

header ("Pragma-directive: no-cache");
header ("Cache-directive: no-cache");
header ("Cache-control: no-cache");
header ("Pragma: no-cache");
header ("Expires: 0");

1
यह पूरे पृष्ठ के लिए अपील करेगा .... मैं केवल एक छवि के लिए कैश को अक्षम नहीं कर सकता (उस पृष्ठ से एक विशिष्ट छवि)?
डोल डग '

5
@ थोरपे: यह HTTP प्रतिक्रियाओं पर लागू होता है। प्रतिक्रिया में जो कुछ भी निहित है वह अप्रासंगिक है। चाहे वह इमेज डेटा हो, एचटीएमएल डेटा हो या जो भी हो। यदि यह काम नहीं करता है, तो आप शायद इसे सही नहीं करते हैं। आपकी प्रतिक्रिया पर HTTP शीर्ष लेख देखें कि क्या उन्हें सही ढंग से सौंपा गया है।
लहनाथ

काश, यह काम किया जाता ... क्रोम को कोई समस्या नहीं है, लेकिन फ़ायरफ़ॉक्स 14 और IE 8 उपरोक्त हेडर के साथ भी छवियों को ताज़ा करने से इनकार करते हैं। यह क्वेरी स्ट्रिंग में कुछ मनमाना मापदंडों को जोड़ने की तुलना में बहुत अधिक क्लीनर समाधान होता। sigh
पावेल क्राकोविएक

2
@PawelKrakowiak ध्यान दें कि हेडर जोड़ना उन छवियों के लिए काम नहीं करेगा जो पहले से ही कैश हैं , क्योंकि ब्राउज़र सर्वर से उनके बारे में भी नहीं पूछता है और इसलिए हेडर कभी नहीं देखेगा। आपके द्वारा जोड़े जाने के बाद वे किसी भी छवि अनुरोध के लिए काम करेंगे।
लहनाथ

2
यह समाधान प्रोग्रामर के लिए है, न कि वेब डिजाइनर के लिए। मैंने सोचा था कि मैं इसे इंगित करूंगा क्योंकि कोई व्यक्ति केवल छवि नहीं खोल सकता है और हेडर को एक छवि में जोड़ सकता है, जब तक कि वे स्वयं एक प्रोग्रामिंग भाषा में छवि उत्पन्न नहीं कर रहे हैं और यह भ्रामक टिप्पणी करने वाले प्रतीत होते हैं।
ब्रूस

13

यदि आपको जावास्क्रिप्ट का उपयोग करके ब्राउज़र में इसे गतिशील रूप से करने की आवश्यकता है, तो यहां एक उदाहरण है ...

<img id=graph alt="" 
  src="http://www.kitco.com/images/live/gold.gif" 
  />

<script language="javascript" type="text/javascript">
    var d = new Date(); 
    document.getElementById("graph").src = 
      "http://www.kitco.com/images/live/gold.gif?ver=" + 
       d.getTime();
</script>

12

समाधान 1 महान नहीं है। यह काम करता है, लेकिन आपकी छवि फ़ाइलों के अंत में hacky यादृच्छिक या टाइमस्टैम्प्ड क्वेरी स्ट्रिंग्स को जोड़ने से ब्राउज़र को हर छवि के हर संस्करण को फिर से डाउनलोड और कैश किया जाएगा, हर बार एक पृष्ठ लोड होने के बावजूद, मौसम की परवाह किए बिना छवि बदल गई है या नहीं। सर्वर पर।

समाधान 2 बेकार है। nocacheएक छवि फ़ाइल में हेडर जोड़ना न केवल लागू करना बहुत कठिन है, बल्कि यह पूरी तरह से अव्यावहारिक है, क्योंकि आपको यह अनुमान लगाने की आवश्यकता है कि इसकी आवश्यकता कब होगी , पहली बार जब आप किसी छवि को लोड करते हैं जो आपको लगता है कि भविष्य में किसी बिंदु पर बदल सकता है। ।

Etags दर्ज करें ...

पूर्ण सबसे अच्छा तरीका है मैं इस को हल करने के पाया है उपयोग करने के लिए है ETAGS एक .htaccess अंदर अपनी छवियों निर्देशिका में फ़ाइल। निम्नलिखित अपाचे को छवि फ़ाइल हेडर में ब्राउज़र को एक अद्वितीय हैश भेजने के लिए कहता है। यह हैश केवल कभी बदलता है जब समय छवि फ़ाइल को संशोधित किया जाता है और यह परिवर्तन अगली बार अनुरोध किए जाने पर छवि को फिर से लोड करने के लिए ब्राउज़र को ट्रिगर करता है।

<FilesMatch "\.(jpg|jpeg)$">
FileETag MTime Size
</FilesMatch>

11

मैंने सभी उत्तरों की जाँच की और सबसे अच्छा लग रहा था (जो नहीं है):

<img src="image.png?cache=none">

सर्वप्रथम।

हालाँकि, यदि आप कैश जोड़ते हैं = कोई भी पैरामीटर (जो कि "कोई भी" शब्द स्थिर नहीं है), यह कुछ भी प्रभाव नहीं डालता है, फिर भी ब्राउज़र कैश से लोड होता है।

इस समस्या का हल था:

<img src="image.png?nocache=<?php echo time(); ?>">

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

हालाँकि, मेरी समस्या थोड़ी अलग थी: मैं फ्लाई जनरेट php चार्ट छवि पर लोड कर रहा था, और $ _GET मापदंडों के साथ पृष्ठ को नियंत्रित कर रहा था। मैं चाहता था कि छवि को कैश से पढ़ा जाए जब URL GET पैरामीटर समान रहता है, और GET पैरामीटर बदलते समय कैश नहीं करते हैं।

इस समस्या को हल करने के लिए, मुझे $ _GET की आवश्यकता है, लेकिन चूंकि यह यहाँ है, इसका समाधान है:

$chart_hash = md5(implode('-', $_GET));
echo "<img src='/images/mychart.png?hash=$chart_hash'>";

संपादित करें :

यद्यपि उपरोक्त समाधान ठीक काम करता है, कभी-कभी आप कैश किए गए संस्करण UNTIL की सेवा करना चाहते हैं फ़ाइल बदल जाती है। (उपरोक्त समाधान के साथ, यह पूरी तरह से उस छवि के लिए कैश को निष्क्रिय कर देता है) इसलिए, ब्राउज़र UNTIL से कैश्ड छवि की सेवा करने के लिए छवि फ़ाइल के उपयोग में बदलाव होता है:

echo "<img src='/images/mychart.png?hash=" . filemtime('mychart.png') . "'>";

filemtime () फ़ाइल संशोधन समय हो जाता है।


4

मुझे पता है कि यह विषय पुराना है, लेकिन यह Google में बहुत अच्छा है। मुझे पता चला कि इसे आपके हेडर में डालने से काम चल जाता है;

<meta Http-Equiv="Cache-Control" Content="no-cache">
<meta Http-Equiv="Pragma" Content="no-cache">
<meta Http-Equiv="Expires" Content="0">
<meta Http-Equiv="Pragma-directive: no-cache">
<meta Http-Equiv="Cache-directive: no-cache">

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

4

मैं बस इसके समाधान की तलाश में था, और ऊपर दिए गए उत्तर मेरे मामले में काम नहीं करते थे (और मेरे पास उन पर टिप्पणी करने के लिए अपर्याप्त प्रतिष्ठा है)। यह पता चला है कि, कम से कम मेरे उपयोग-केस और मेरे द्वारा उपयोग किए जा रहे ब्राउज़र (OSX पर Chrome) के लिए, केवल वही चीज़ जो कैशिंग को रोकने के लिए लग रहा था:

Cache-Control = 'no-store'

पूर्णता के लिए मैं अब 'नो-कैश, नो-स्टोर, मस्ट-रिवाइल्ड' के सभी 3 का उपयोग कर रहा हूं

तो मेरे मामले में (पायथन में फ्लास्क से गतिशील रूप से उत्पन्न छवियां परोसते हुए), मुझे आशा है कि जितना संभव हो उतने ब्राउज़र में काम करना होगा ...

def make_uncached_response(inFile):
    response = make_response(inFile)
    response.headers['Pragma-Directive'] = 'no-cache'
    response.headers['Cache-Directive'] = 'no-cache'
    response.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate'
    response.headers['Pragma'] = 'no-cache'
    response.headers['Expires'] = '0'
    return response

सिर्फ प्रतिक्रिया के लिए कोई स्टोर नहीं करना मेरे लिए काम करने के लिए पर्याप्त था
19-21 पर scourge192

यह सिर्फ क्रोम पर ही नहीं, फायरफॉक्स के लिए भी है। यह अब एक मानक प्रतीत होता है: developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control (" कैशिंग रोकना " अनुभाग देखें)।
गीनो मेम्पिन

3

छवि स्रोत को बदलना इसका समाधान है। आप वास्तव में छवि में टाइमस्टैम्प या यादृच्छिक संख्या जोड़कर ऐसा कर सकते हैं।

बेहतर होगा उदाहरण के लिए डेटा का एक चेकसम जोड़ना होगा जो छवि का प्रतिनिधित्व करता है। यह संभव होने पर कैशिंग को सक्षम करता है।


1

चलो गुच्छा में एक और समाधान जोड़ें।

अंत में एक अद्वितीय स्ट्रिंग जोड़ना एक सही समाधान है।

example.jpg?646413154

निम्नलिखित समाधान इस विधि का विस्तार करता है और दोनों कैशिंग क्षमता प्रदान करता है और छवि अपडेट होने पर एक नया संस्करण प्राप्त करता है।

जब छवि को अपडेट किया जाता है, तो फिल्म का समय बदल दिया जाएगा।

<?php
$filename = "path/to/images/example.jpg";
$filemtime = filemtime($filename);
?>

अब छवि का उत्पादन करें:

<img src="images/example.jpg?<?php echo $filemtime; ?>" >

1
यही कारण है कि मैं वैधता कैशिंग के कारण इस्तेमाल किया।
जीन


0

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

मैंने कम से कम हर मिनट को ताज़ा सुनिश्चित करने के लिए एक तारीख स्ट्रिंग संलग्न किया है।

नमूना कोड (PHP):

$output .= "<img src=\"http://xy.somecounter.com/?id=1234567890&".date(ymdHi)."\" alt=\"somecounter.com\" style=\"border:none;\">";

इस srcतरह एक लिंक में परिणाम :

http://xy.somecounter.com/?id=1234567890&1207241014

0

यदि आपके पास हार्डकोड इमेज URL है, उदाहरण के लिए: http://example.com/image.jpg आप अपनी छवि में हेडर जोड़ने के लिए php का उपयोग कर सकते हैं।

सबसे पहले आपको अपने jpg को php के रूप में अपाचे प्रोसेस करना होगा। यहाँ देखें: क्या PHP को एक्सटेंशन file.php.jpg के साथ निष्पादित करना संभव है?

फ़ाइल से छवि (imagecreatefromjpeg) लोड करें फिर पिछले उत्तरों से हेडर जोड़ें। हेडर जोड़ने के लिए php फ़ंक्शन हेडर का उपयोग करें।

फिर Imagejpeg फ़ंक्शन के साथ छवि को आउटपुट करें।

कृपया ध्यान दें कि यह php प्रक्रिया को jpg इमेजेस देने के लिए बहुत असुरक्षित है। कृपया यह भी जान लें कि मैंने इस समाधान का परीक्षण नहीं किया है, इसलिए यह काम करने के लिए आप पर निर्भर है।


-1

सरल, एक हेडर स्थान भेजें।

मेरी साइट में एक छवि शामिल है, और छवि को अपलोड करने के बाद, वहाँ परिवर्तन नहीं होता है, तो मैं यह कोड जोड़ता हूं:

<?php header("Location: pagelocalimage.php"); ?>

मेरे लिये कार्य करता है।

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