HTTP कैशिंग

HTTP cache किसी response की copy रख लेता है, ताकि उसी resource की अगली request का जवाब origin server (वह server जिसका resource है) तक पूरा सफ़र किए बिना दिया जा सके। आपके browser का अपना private cache होता है; proxy या CDN जैसे shared caches बहुत-से users और server के बीच बैठे होते हैं। RFC 9111 इसके नियम तय करता है, और server उन्हें response headers से सेट करता है।

उदाहरण: एक product page GET /api/products/1042 call करता है, और response में Cache-Control: max-age=60 और ETag: "p1042-v7" हैं। 60 seconds तक browser बिना पूछे अपनी copy दोबारा इस्तेमाल करता है। उसके बाद वह पूछता है कि क्या p1042-v7 अब भी current है; अगर है, तो server बिना body के 304 Not Modified भेजता है।

यह क्यों ज़रूरी है

Caching बार-बार की visits को तेज़ बनाती है और servers का load घटाती है, लेकिन हर cached copy पुरानी हो सकती है या गलत व्यक्ति तक पहुँच सकती है। आम defects: release के बाद पुरानी price या पुरानी script, गलत भाषा में page, और सबसे बुरा: shared cache जो एक customer का account page अगले customer को दिखा दे।

Test environments में अक्सर CDN नहीं होता, और testers अक्सर DevTools का "Disable cache" चालू रखकर काम करते हैं, इसलिए ये defects production में सामने आते हैं, जब तक कोई release से पहले caching headers न पढ़े।

Fresh या stale: Cache-Control क्या तय करता है

Cache response को एक cache key के तहत store करता है, जिसमें कम से कम request method और URL होते हैं; ज़्यादातर stored responses GET requests के successful responses होते हैं। जब तक stored response fresh है, cache उसे server से संपर्क किए बिना दोबारा इस्तेमाल कर सकता है। Stale होने के बाद cache को आम तौर पर पहले server से जाँच करनी पड़ती है।

Freshness lifetime max-age से आती है, वरना पुराने Expires header से, जिसमें एक तय date होती है और जिसे max-age मौजूद होने पर ignore किया जाता है। दोनों न हों तो cache ख़ुद lifetime का अंदाज़ा लगा सकता है (heuristic freshness), अक्सर Last-Modified से। इसलिए बिना caching headers वाला response "uncached" नहीं होता, बस उसका व्यवहार अनिश्चित होता है।

  • max-age=600: 600 seconds तक fresh। s-maxage सिर्फ़ shared caches के लिए lifetime तय करता है।
  • no-cache: store किया जा सकता है, लेकिन हर reuse से पहले server से revalidate करना ज़रूरी है। नाम के बावजूद यह caching नहीं रोकता।
  • no-store: कोई भी cache request या response store नहीं कर सकता। Personal और sensitive data के लिए यही directive है।
  • private: सिर्फ़ user का अपना (private) cache इसे store कर सकता है। public: कोई भी cache store कर सकता है, वहाँ भी जहाँ वैसे नहीं करता।
  • must-revalidate: stale होने के बाद successful check के बिना copy इस्तेमाल नहीं हो सकती, चाहे server तक पहुँच न हो।
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: max-age=60
ETag: "p1042-v7"
Last-Modified: Wed, 30 Sep 2026 08:00:00 GMT
Date: Thu, 01 Oct 2026 09:00:00 GMT

आज़माएँ: कैश हेडर एनालाइज़र आज़माएँ: HTTP हेडर बिल्डर

Revalidation: ETag, Last-Modified और 304

Stale copy को सस्ते में जाँचने के लिए server हर response पर एक validator लगाता है: ETag, यानी "p1042-v7" जैसा opaque version tag, या Last-Modified, यानी एक date। Cache इसे conditional request में वापस भेजता है: ETag के लिए If-None-Match, date के लिए If-Modified-Since। दोनों हों तो RFC 9110 के अनुसार server If-Modified-Since को ignore करता है।

कुछ नहीं बदला हो तो server 304 Not Modified भेजता है: body नहीं, सिर्फ़ ETag, Cache-Control और Date जैसे headers, जिनसे stored copy refresh होती है और client फिर वही copy दिखाता है। Resource बदल गया हो तो server नई body और नए ETag के साथ 200 OK भेजता है। W/ से शुरू होने वाला ETag weak होता है: वह equivalent content का वादा करता है, byte-for-byte identical content का नहीं।

Stale copy को If-None-Match से revalidate किया जाता है: ETag मेल खाए तो server बिना body के 304 Not Modified भेजता है; product बदला हो तो नई body और नए ETag के साथ 200 OK भेजता है।
  • Product नहीं बदला

    • ब्राउज़र private cache
    • Origin server shop.example
    1. 1 ब्राउज़र से Origin server तक: पहली request GET /api/products/1042
    2. 2 Origin server से ब्राउज़र तक: Body और validator के साथ 200 OK जवाब Cache-Control: max-age=60 ETag: "p1042-v7"
    3. 3 ब्राउज़र आंतरिक रूप से: बिना पूछे stored copy दोबारा इस्तेमाल करता है 60 seconds तक fresh: कोई request नहीं जाती
    4. 4 ब्राउज़र से Origin server तक: Copy stale है: conditional request If-None-Match: "p1042-v7"
    5. 5 Origin server आंतरिक रूप से: ETag मिलाता है: अब भी current
    6. 6 Origin server से ब्राउज़र तक: 304 Not Modified, बिना body जवाब नए Date और Cache-Control stored copy को refresh करते हैं पास

    परिणाम: Browser वही body दिखाता है जो उसके पास है, अगले 60 seconds के लिए fresh।

  • Product बदल गया

    • ब्राउज़र private cache
    • Origin server shop.example
    1. 1 ब्राउज़र से Origin server तक: Copy stale है: conditional request If-None-Match: "p1042-v7"
    2. 2 Origin server आंतरिक रूप से: ETag मिलाता है: price बदल गई Current version p1042-v8 है
    3. 3 Origin server से ब्राउज़र तक: नई body के साथ 200 OK जवाब ETag: "p1042-v8"
    4. 4 ब्राउज़र आंतरिक रूप से: Stored copy को बदल देता है

    परिणाम: नई price दिखती है, और अगली conditional request "p1042-v8" भेजती है।

GET /api/products/1042 HTTP/1.1
Host: shop.example
If-None-Match: "p1042-v7"

HTTP/1.1 304 Not Modified
Cache-Control: max-age=60
ETag: "p1042-v7"
Date: Thu, 01 Oct 2026 09:01:05 GMT

आज़माएँ: cURL जनरेटर आज़माएँ: HTTP हेडर पार्सर

Shared और private caches

Private cache एक user की सेवा करता है, आम तौर पर browser। Shared cache बहुत-से users के लिए responses store करता है: proxy, CDN, या application के आगे लगा reverse proxy। RFC 9111 default रूप से एक case को बचाता है: shared cache Authorization header वाली request के response को तब तक reuse नहीं कर सकता जब तक response ख़ुद इसकी अनुमति न दे, जैसे public या s-maxage से।

Session cookie को ऐसी सुरक्षा नहीं मिलती, इसलिए personalised response को ख़ुद private या no-store कहना होगा। Authentication and authorization वाले lesson में आपने जाँचा था कि कौन-सा data कौन देख सकता है; shared cache एक और रास्ता है जिससे गलत व्यक्ति वह data देख सकता है।

  • Vary उन request headers के नाम बताता है जिन पर response निर्भर है, जैसे Vary: Accept-Language। इसके बिना shared cache English माँगने वाले को Arabic page दे सकता है।
  • Successful POST, PUT या DELETE उस URL की stored copy सिर्फ़ उन caches में invalidate करता है जिनसे request गुज़रती है; बाकी caches अपनी copy stale या purge होने तक रखते हैं।
  • Age header का मतलब है कि response किसी cache से आया। कई CDNs अपना एक header भी जोड़ते हैं जो hit या miss बताता है; उसका नाम vendor पर निर्भर है।

Worked example: CDN के पीछे product page की testing

एक store अपने product pages CDN से serve करता है। नियम: नई price एक मिनट के अंदर दिखे, और account pages कभी cache न हों। इन नियमों को हर तरह के response के expected headers में बदलें, फिर दोहराई जा सकने वाली requests (curl, API tools या DevTools का Network panel) से व्यवहार टेस्ट करें, और लिखें कि हर page link से खुला, normal reload से या hard reload से।

  • app.3f9c1a.js जैसी versioned file: लंबा max-age सही है, क्योंकि हर release को नया file name मिलता है।
  • max-age=60 और ETag वाला product API: If-None-Match के साथ request दोहराएँ और बिना body के 304 की उम्मीद करें। Price बदलें, 60 seconds रुकें, दोहराएँ: नई price और नए ETag के साथ 200 की उम्मीद करें।
  • CDN के ज़रिए: वही request दो बार भेजें और जाँचें कि Age दिखता है और बढ़ता है। फिर उसे Accept-Language: ar और फिर en के साथ भेजें और दोनों bodies मिलाएँ।
  • Account pages: no-store की उम्मीद करें। Orders वाला वही URL दो browsers में customer A और customer B के रूप में खोलें; B को A के orders कभी नहीं दिखने चाहिए। Logout के बाद Back button private data न दिखाए; इसे हर target browser में टेस्ट करें, क्योंकि RFC 9111 browser history को caching rules मानने के लिए बाध्य नहीं करता।

आज़माएँ: API हेडर वैलिडेटर

आम गलतियाँ

  • no-cache को "cache मत करो" समझना; इसका मतलब "reuse से पहले revalidate करो" है, और store करने से no-store रोकता है।
  • मान लेना कि बिना caching headers वाला response कभी cache नहीं होता; cache ख़ुद उसकी lifetime का अंदाज़ा लगा सकता है।
  • हमेशा "Disable cache" चालू रखकर, या सिर्फ़ बिना CDN वाले environment में टेस्ट करके मान लेना कि caching ठीक है।
  • यह जाँचना कि 304 आया, पर यह नहीं कि उसके बाद page current content दिखाता है।
  • Personalised pages को एक ही account से टेस्ट करना; users के बीच leak पकड़ने के लिए दो accounts चाहिए।
  • जब response भाषा या किसी दूसरे request header पर निर्भर हो, तब Vary भूल जाना।

QA का नज़रिया

Caching code में, web server में और CDN में configure होती है, अक्सर अलग-अलग लोगों द्वारा। Refinement के दौरान पूछें कि हर तरह का data कितना fresh होना चाहिए, और जवाब testable रूप में लिखें, जैसे "prices: 60 seconds से ज़्यादा पुरानी नहीं; account pages: कभी store नहीं"। यही आपके expected results हैं।

Caching bug report में पूरे request और response headers, किस cache ने जवाब दिया (उसके Age या hit/miss header के साथ), हर request का समय और page कैसे load हुआ, यह सब लिखें; वरना खाली cache के साथ reload करने वाला developer इसे reproduce नहीं कर पाएगा। हर CDN configuration बदलाव के बाद caching दोबारा टेस्ट करें।

अभ्यास

एक online store के caching headers review करें

आपका काम

नीचे के पाँच exchanges CDN के पीछे चल रहे एक store के हैं। नियम: prices 60 seconds से ज़्यादा पुरानी नहीं हो सकतीं, कोई cache account data store नहीं कर सकता, और product data Accept-Language में माँगी गई भाषा में आता है। Response 2 वह product page है जो price दिखाता है; exchange 5 में product नहीं बदला है।

तय करें कि हर response की caching सही है या नहीं, और मिली हर problem का वर्णन करें।

सामग्री
1) GET /assets/app.3f9c1a.js
   -> 200 OK
      Cache-Control: public, max-age=31536000

2) GET /products/1042
   -> 200 OK
      Content-Type: text/html
      Cache-Control: public, max-age=86400

3) GET /api/account/orders
   Authorization: Bearer <access token>
   -> 200 OK
      Cache-Control: public, max-age=300

4) GET /api/products/1042
   Accept-Language: ar
   -> 200 OK
      Content-Language: ar
      Cache-Control: max-age=60
      ETag: "p1042-v7"
      Vary: Accept-Encoding

5) GET /api/products/1042
   If-None-Match: "p1042-v7"
   -> 200 OK
      ETag: "p1042-v7"
      Content-Length: 5120
चरण
  1. हर response के लिए लिखें कि उसे कौन store कर सकता है (browser, shared caches, कोई नहीं) और कितनी देर।
  2. इसकी तुलना content और नियमों से करें।
  3. हर problem के लिए risk, expected headers और एक test लिखें जो असली caches से होकर जाए।
मॉडल उत्तर दिखाएँ
मॉडल उत्तर

Response 1 सही है: version file name का हिस्सा है, इसलिए हर release URL बदल देता है और एक साल का max-age पुराना code नहीं दे सकता।

Response 2 defect है: कोई भी cache 24 घंटे तक पुरानी price दिखा सकता है। Expected: max-age=60, या ETag के साथ no-cache। Test: price बदलें और 61 seconds बाद CDN के ज़रिए page खोलें।

Response 3 high severity का security defect है: public shared cache को Authorization वाली request का response reuse करने देता है, इसलिए CDN एक customer के orders दूसरे को दिखा सकता है। Expected: no-store। Test: दो accounts, वही URL, CDN के ज़रिए; हर एक को सिर्फ़ अपने orders दिखने चाहिए।

Response 4 defect है: body Accept-Language पर निर्भर है, लेकिन Vary में वह नहीं है, इसलिए CDN English request को Arabic body दे सकता है। Expected: Vary: Accept-Encoding, Accept-Language। Test: पहले Arabic में, फिर English में request करें और Content-Language मिलाएँ।

Response 5 defect है: ETag मेल खाता है, इसलिए सही जवाब बिना body का 304 Not Modified है। 5,120 bytes दोबारा भेजना bandwidth बर्बाद करता है पर गलत data नहीं दिखाता, इसलिए इसकी severity response 3 से कम है। इस response में Cache-Control भी नहीं है, इसलिए caches उसकी lifetime का अंदाज़ा ख़ुद लगा सकते हैं। Expected: ETag, Cache-Control: max-age=60 और ठीक किए गए response 4 जैसे Vary के साथ 304। Test: conditional request दोहराएँ और 304 की उम्मीद करें।

अक्सर पूछे जाने वाले सवाल

no-cache और no-store में क्या फ़र्क है?

no-cache response को store करने देता है, लेकिन हर reuse से पहले server से revalidation ज़रूरी करता है, इसलिए user को हमेशा current content मिलता है, अक्सर सस्ते 304 के ज़रिए। no-store request और response को store करना पूरी तरह रोकता है। Personal या sensitive data के लिए no-store इस्तेमाल करें।

Server ETag भेजे या Last-Modified?

दोनों validator का काम करते हैं और servers अक्सर दोनों भेजते हैं, पर ETag ज़्यादा सटीक है: Last-Modified की precision एक second है, और file उसी content के साथ दोबारा save होने पर भी यह बदल सकता है। अगर request में दोनों conditions हों, तो server If-None-Match इस्तेमाल करता है और If-Modified-Since को ignore करता है।

Test environment में CDN न हो तो caching कैसे टेस्ट करूँ?

Headers वहीं जाँचें, क्योंकि उन्हें application सेट करती है। Shared cache का व्यवहार (Age, hit या miss, Vary, users के बीच leaks) ऐसे environment में टेस्ट करें जिसमें production जैसी CDN या proxy configuration हो, जैसे staging। ऐसा environment न हो तो यह gap test plan में लिखें।

Browser कुछ files के लिए कोई request ही क्यों नहीं भेजता?

क्योंकि वे fresh हैं: max-age के अंदर browser server से संपर्क किए बिना अपनी copy इस्तेमाल करता है, और Network panel दिखाता है कि वे cache से आईं। Conditional request तब जाती है जब copy stale हो या no-cache वाली हो, और browser के हिसाब से reload भी उसे भेज सकता है।

संदर्भ

  • RFC 9111: HTTP CachingIETF · 2022Cache-Control, Expires, ETag और वैलिडेटर कैसे तय करते हैं कि रिस्पॉन्स स्टोर और पुन: उपयोग हो सकता है या नहीं।
  • RFC 9110: HTTP SemanticsIETF · 2022HTTP मेथड, हेडर फ़ील्ड, स्टेटस कोड और कंटेंट निगोशिएशन के अर्थ, वायर वर्ज़न से स्वतंत्र।
  • HTTP caching — MDNMDN Web Docs (Mozilla)प्राइवेट बनाम शेयर्ड कैश, फ़्रेशनेस, ETag / Last-Modified से वैलिडेशन और आम Cache-Control पैटर्न।
  • OWASP Cheat Sheet Series: Session ManagementOWASP Foundationसेशन आइडेंटिफ़ायर की एंट्रॉपी, कुकी एट्रिब्यूट, एक्सपायरी, लॉगिन के बाद नवीनीकरण और लॉगआउट हैंडलिंग।

Mutqan tools से अभ्यास करें

Cache-Control, Expires, ETag, Last-Modified, Vary और Age हेडर जाँचें और समझें कि ब्राउज़र तथा CDN रिस्पॉन्स को कैसे कैश करेंगे।

वैलिडेशन

कच्चे HTTP रिक्वेस्ट/रिस्पॉन्स हेडर को व्याख्या सहित एक संरचित तालिका में बदलें।

वेब

caching, CORS, security और content negotiation के प्रीसेट से HTTP हेडर तैयार करें।

वेब

API रिस्पॉन्स हेडर की शुद्धता, सुरक्षा और caching की सर्वोत्तम प्रथाओं के लिए जाँच करें।

API टेस्टिंग

मेथड, URL, हेडर, बॉडी और auth विकल्पों से cURL कमांड बनाएँ।

वेब

और गहराई से

इस topic में आपकी प्रगति

QA रोडमैप का हिस्सा