2010-05-01 13 views
5

में संग्रहीत छवियों के लिए "304 संशोधित नहीं" भेजें, the docs में प्रस्तावित अनुसार, Google App Engine डेटास्टोर में उपयोगकर्ता द्वारा अपलोड की गई छवियों को db.Blob पर संग्रहीत करें। मैं फिर उन छवियों को /images/<id>.jpg पर सेवा देता हूं।डेटास्टोर

सर्वर हमेशा 200 OK प्रतिक्रिया भेजता है, जिसका अर्थ है कि ब्राउज़र को एक ही छवि को एकाधिक समय (== धीमी) डाउनलोड करना होगा और सर्वर को एक ही छवि को कई बार (== अधिक महंगा) भेजना होगा।

चूंकि इनमें से अधिकतर छवियां कभी भी नहीं बदलेगी, मैं 304 Not Modified प्रतिक्रिया भेजने में सक्षम होना चाहता हूं। मैं चित्र जब उपयोगकर्ता इसे अपलोड करता है के हैश के कुछ प्रकार की गणना के बारे में सोच रहा है, और फिर जानना चाहते हैं कि उपयोगकर्ता पहले से ही इस छवि है इस का उपयोग (शायद एक Etag के रूप में हैश भेज?)

मैं this answer पाया और है this answer कि तर्क बहुत अच्छी तरह से समझाने, लेकिन मैं 2 प्रश्न हैं:

  1. क्या यह संभव है गूगल एप इंजन में एक Etag भेजने के लिए?
  2. क्या किसी ने इस तरह के तर्क लागू किए हैं, और/या कोई कोड स्निपेट उपलब्ध है?

उत्तर

7

Bloggart इस तकनीक का उपयोग करता है। this blog post पर एक नज़र डालें।

class StaticContentHandler(webapp.RequestHandler): 
    def output_content(self, content, serve=True): 
    self.response.headers['Content-Type'] = content.content_type 
    last_modified = content.last_modified.strftime(HTTP_DATE_FMT) 
    self.response.headers['Last-Modified'] = last_modified 
    self.response.headers['ETag'] = '"%s"' % (content.etag,) 
    if serve: 
     self.response.out.write(content.body) 
    else: 
     self.response.set_status(304) 

    def get(self, path): 
    content = get(path) 
    if not content: 
     self.error(404) 
     return 

    serve = True 
    if 'If-Modified-Since' in self.request.headers: 
     last_seen = datetime.datetime.strptime(
      self.request.headers['If-Modified-Since'], 
      HTTP_DATE_FMT) 
     if last_seen >= content.last_modified.replace(microsecond=0): 
     serve = False 
    if 'If-None-Match' in self.request.headers: 
     etags = [x.strip('" ') 
       for x in self.request.headers['If-None-Match'].split(',')] 
     if content.etag in etags: 
     serve = False 
    self.output_content(content, serve) 
+0

उत्कृष्ट उदाहरण! ;) –

+0

मैंने इस उदाहरण के आधार पर अपना समाधान लागू किया है, और सब कुछ ठीक काम करता है। धन्यवाद जॉबो और निक! – Emilien

0

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

बस अपने अनुरोध हैंडलर से दूर भविष्य तक Expires शीर्षलेख सेट करें, उदा। अब + एक साल। इसके परिणामस्वरूप क्लाइंट छवि को कैश कर रहे हैं और उस समय तक अपडेट की मांग नहीं करेंगे।

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

+0

यह वास्तव में एक संभावित समाधान होगा। जैसा कि मैंने कहा, मैं छवियों को बदलने की उम्मीद नहीं करता, लेकिन आप कभी नहीं जानते। मैं निक के समाधान में देखने जा रहा हूं, क्योंकि मेरे पास उन छवियों की तुलना में अन्य स्थिर सामग्री होगी, और वे बदल सकते हैं, इसलिए सभी के लिए एक समाधान सबसे अच्छा लगता है। हालांकि धन्यवाद! – Emilien

0

वैसे, वेबोब के लिए धन्यवाद, webapp.RequestHandler if-None-Match की जांच करने का आसान तरीका प्रदान करता है।

if etag in self.request.if_none_match: 
    pass # do something 
0

क्यों कोड उपयोग इस होगा:

self.response.headers['ETag'] = '"%s"' % (content.etag,) 
बजाय इस बात का

:

self.response.headers['ETag'] = '"%s"' % content.etag 

मुझे लगता है कि यह एक ही है और जब तक कि कोई तर्क बताते हैं 2 का प्रयोग करेंगे।

संबंधित मुद्दे