Я храню пользовательские загруженные изображения в хранилище данных Google App Engine как db.Blob
, как предложено в документах. Я затем вручаю те изображения на /images/
.
Сервер всегда отправляет a 200 OK
ответ, что означает, что браузер должен загрузить то же изображение несколько время (== медленнее) и что сервер должен отправить то же изображение многократно (== более дорогой).
Поскольку большинство тех изображений никогда не будет, вероятно, изменяться, я хотел бы смочь отправить a 304 Not Modified
ответ. Я думаю о вычислении некоторого хеша изображения, когда пользователь загружает его, и затем используйте это, чтобы знать, есть ли у пользователя уже это изображение (возможно, отправляют хеш как Etag
?)
Я нашел этот ответ и этот ответ, которые объясняют логику вполне прилично, но у меня есть 2 вопроса:
Etag
в Google App Engine?Bloggart использует эту технику. Посмотрите это сообщение в блоге .
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)
Здесь может быть более простое решение. Это требует, чтобы вы никогда не перезаписывали данные, связанные с каким-либо идентификатором, например. изменение изображения приведет к созданию нового идентификатора (и, следовательно, нового URL-адреса).
Просто установите заголовок Expires
из обработчика запросов на далекое будущее, например сейчас + год. Это приведет к тому, что клиенты будут кэшировать изображение и не запрашивать обновление до тех пор, пока не придет время.
У этого подхода есть некоторые компромиссы, например, обеспечение встраивания новых URL-адресов при изменении изображений, поэтому вы должны решить для себя. То, что предлагает jbochi, - это другая альтернатива, которая добавляет больше логики в обработчик запроса изображения.