Отправьте “304, Не Измененные” для изображений, сохраненных в хранилище данных

Я храню пользовательские загруженные изображения в хранилище данных Google App Engine как db.Blob, как предложено в документах. Я затем вручаю те изображения на /images/.jpg.

Сервер всегда отправляет a 200 OK ответ, что означает, что браузер должен загрузить то же изображение несколько время (== медленнее) и что сервер должен отправить то же изображение многократно (== более дорогой).

Поскольку большинство тех изображений никогда не будет, вероятно, изменяться, я хотел бы смочь отправить a 304 Not Modified ответ. Я думаю о вычислении некоторого хеша изображения, когда пользователь загружает его, и затем используйте это, чтобы знать, есть ли у пользователя уже это изображение (возможно, отправляют хеш как Etag?)

Я нашел этот ответ и этот ответ, которые объясняют логику вполне прилично, но у меня есть 2 вопроса:

  1. Действительно ли возможно отправить Etag в Google App Engine?
  2. Кто-либо реализовал такую логику и/или является там каким-либо доступным фрагментом кода?

5
задан Community 23 May 2017 в 12:09
поделиться

2 ответа

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)
8
ответ дан 14 December 2019 в 04:32
поделиться

Здесь может быть более простое решение. Это требует, чтобы вы никогда не перезаписывали данные, связанные с каким-либо идентификатором, например. изменение изображения приведет к созданию нового идентификатора (и, следовательно, нового URL-адреса).

Просто установите заголовок Expires из обработчика запросов на далекое будущее, например сейчас + год. Это приведет к тому, что клиенты будут кэшировать изображение и не запрашивать обновление до тех пор, пока не придет время.

У этого подхода есть некоторые компромиссы, например, обеспечение встраивания новых URL-адресов при изменении изображений, поэтому вы должны решить для себя. То, что предлагает jbochi, - это другая альтернатива, которая добавляет больше логики в обработчик запроса изображения.

0
ответ дан 14 December 2019 в 04:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: