2010-05-01 3 views
5

the docs에서 제안 된대로 사용자가 업로드 한 이미지를 Google App Engine 데이터 저장소에 db.Blob으로 저장합니다. 그런 다음 /images/<id>.jpg에 해당 이미지를 제공합니다.데이터 저장소에 저장된 이미지에 "304 Not Modified"전송

서버는 항상 200 OK 응답을 전송합니다. 즉, 브라우저는 동일한 이미지를 여러 번 (= 느리게) 다운로드해야하며 서버는 동일한 이미지를 여러 번 (= 더 비싸게) 보내야 함을 의미합니다.

대부분의 이미지가 변경되지 않으므로 304 Not Modified 응답을 보내고 싶습니다. 사용자가 업로드 할 때 그림의 해시 계산을 생각한 다음 사용자가 이미이 이미지를 가지고 있는지 (예 : Etag으로 해시를 보내면 알 수 있습니까?)

나는 this answer을 발견했습니다.

  1. 이 가능 구글 앱 엔진에서 Etag을 보낼 : 꽤 잘 논리를 설명하지만, 나는이 개 질문이 this answer?
  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

이 예제를 기반으로 솔루션을 구현했지만 모든 것이 잘 동작합니다. 감사합니다 jbochi 및 닉! – Emilien

0

여기에는 더 간단한 해결책이있을 수 있습니다. 이를 위해서는 식별자와 관련된 데이터를 덮어 쓰지 않아야합니다. 이미지를 수정하면 새 ID (따라서 새 URL)가 작성됩니다.

요청 처리기의 Expires 헤더를 먼 미래에 설정하기 만하면됩니다. 지금 + 1 년. 이로 인해 클라이언트가 이미지를 캐싱하고 그 시간까지 업데이트를 요구하지 않게됩니다.

이 접근법은 이미지가 수정 될 때 새 URL이 포함되도록 보장하여 사용자 스스로 결정해야하는 등의 단점을 가지고 있습니다. jbochi가 제안하는 또 다른 대안은 이미지 요청 처리기에 더 많은 로직을 넣는 것입니다.

+0

이것은 실제로 가능한 해결책 일 것입니다. 내가 말했듯이, 나는 이미지가 바뀌 길 기대하지 않지만 결코 알지 못합니다. 나는 그 이미지들보다 다른 정적 인 컨텐트를 가지기 때문에 Nick의 솔루션을 살펴볼 것입니다. 그리고 그것들은 바뀔지도 모릅니다. 그래서 모든 것을위한 하나의 솔루션을 갖는 것이 가장 좋은 것처럼 보입니다. 그래도 고마워! – Emilien

0

그런데 webob 덕택에 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를 사용하는 것이라 생각합니다.

관련 문제