Как получить 304 для изображений, хранящихся на Amazon S3 при использовании django-хранилищ в приложении django? - PullRequest
5 голосов
/ 18 марта 2012

Я только начал хранить загруженные пользователем изображения на Amazon S3. Это довольно мило, потому что он позаботился о моей проблеме с хранением. Однако я испытываю трудности, когда браузер кэширует изображения.

Я использую django-хранилища. В своих документах они указывают, что вы можете поместить вещи в заголовок запроса для изображения, установив переменную AWS_HEADER в своих настройках. Я делаю это и не получаю результатов.

Обычно, когда приложение запрашивает изображения, я получаю 200 КАЖДЫЙ РАЗ. ARG ... когда я беру браузер прямо к изображению (копирую и вставляю ссылку в новое окно), я получаю 200, а затем 304 каждый раз после этого.

Это очень расстраивает, потому что каждый раз загружает изображение. На некоторых страницах есть до 25 маленьких миниатюр, и они перезагружают все каждый раз, когда страница перезагружается.

Я передаю свои статические файлы, используя статические файлы djangos, и они работают правильно. Я получаю 200, а затем 304 после того, как файл кэшируется.

вот мои настройки AWS в settings.py

DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
AWS_ACCESS_KEY_ID = '***'
AWS_SECRET_ACCESS_KEY = '***'
AWS_STORAGE_BUCKET_NAME = 'foobar_uploads'
AWS_HEADERS = {
    'Expires': 'Thu, 15 Apr 2020 20:00:00 GMT',
    'Cache-Control': 'max-age=86400',
}

AWS_CALLING_FORMAT = CallingFormat.SUBDOMAIN

вот заголовки запроса и ответа, когда приложение запрашивает изображение: (я заменил то, что, по моему мнению, может быть конфиденциальной информацией, на '*')

##request##
GET /user_uploads/*****/2012/3/17/14/46/thumb_a_28_DSC_0472.jpg?Signature=FVR6T%2BXFwHMmdQ9K3n7Ppp7QxoY%3D&Expires=1332023525&AWSAccessKeyId=***** HTTP/1.1
Host: *****_user_uploads_sandbox.s3.amazonaws.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.79 Safari/535.11
Accept: */*
Referer: http://localhost:8000/m/my-photos/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3


##response##
HTTP/1.1 200 OK
x-amz-id-2: Hn3S+3gmeLHIjKCpz+2ocE6aPsLCVHh56jJYTsPHwxU98y89x+9X1Ml202evBUHT
x-amz-request-id: 528CEB880CA89AD3
Date: Sat, 17 Mar 2012 21:32:06 GMT
Cache-Control: max-age=86400
Expires: Thu, 15 Apr 2020 20:00:00 GMT
Last-Modified: Sat, 17 Mar 2012 20:46:29 GMT
ETag: "a3bc70e0c3fc0deb974edf95668e9030"
Accept-Ranges: bytes
Content-Type: image/jpeg
Content-Length: 8608
Server: AmazonS3

вот заголовки запроса / ответа, когда я вручную запрашиваю изображение путем копирования и вставки ссылки на изображение:

##request##
GET /user_uploads/*****/2012/3/17/14/46/thumb_a_28_DSC_0472.jpg?Signature=FVR6T%2BXFwHMmdQ9K3n7Ppp7QxoY%3D&Expires=1332023525&AWSAccessKeyId=***** HTTP/1.1
Host: porlio_user_uploads_sandbox.s3.amazonaws.com
Connection: keep-alive
Cache-Control: max-age=0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.79 Safari/535.11
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
If-None-Match: "a3bc70e0c3fc0deb974edf95668e9030"
If-Modified-Since: Sat, 17 Mar 2012 20:46:29 GMT



##response##
HTTP/1.1 304 Not Modified
x-amz-id-2: FZH0imrbNxziMznhl5zAoo38CaM7Z+TFnd8R6HtTYB3eTmVpCih+1IniKaliRo18
x-amz-request-id: 3CACF77FBB39D088
Date: Sat, 17 Mar 2012 21:33:22 GMT
Last-Modified: Sat, 17 Mar 2012 20:46:29 GMT
ETag: "a3bc70e0c3fc0deb974edf95668e9030"
Server: AmazonS3

Я вижу, что есть несколько отличий, таких как "If-None-Match:" или "If-Modified-Since:". Я думаю, что если бы я их установил, то он работал бы так, как я хотел бы.

Есть ли простой способ сделать это?

Спасибо за любую помощь!

РЕДАКТИРОВАТЬ 1: Я прочитал эту статью и не смог перевести ее очень хорошо .. http://coder.cl/2012/01/django-and-amazon-s3/comment-page-1/

Ответы [ 2 ]

5 голосов
/ 26 марта 2012

Если вы не хотите, чтобы django-хранилища добавляли запрос аутентификации на статический носитель, добавьте следующее к вашему settings.py:

AWS_QUERYSTRING_AUTH = False

Это вызвано бэкэндом S3 Boto, которыйавтоматически добавит строку запроса, если не указано иное, через django-хранилища.Если вы посмотрите на исходный код для приложения, вы заметите, что оно ищет некоторые дополнительные недокументированные настройки в вашем файле settings.py (около строки 34).

Я ответил наэта похожая проблема возникла на Github для django-компрессора здесь .

1 голос
/ 18 марта 2012

Не похоже, что вы отправляете «If-None-Match» или «If-Modified-Since» в запросе вашего приложения, поэтому S3 не имеет возможности отправить вам обратно 304, так как он понятия не имеетчто у тебя есть.Как вы можете видеть, ваш браузер кэшировал файл, поэтому он отправляет оба этих заголовка и получает правильный ответ 304.

Если вы храните локальные копии файлов, вам необходимо сохранить последний- Модифицированный и / или ETag и отправьте их вместе с вашим запросом на изображение.

В связи с этим, я бы хотел использовать только заголовок max-age и пропустить Expires.Согласно спецификации, Срок действия не должен превышать год в будущем .Использование Expires и max-age является излишним, а max-age можно установить на относительную сумму (как вы это сделали).

Я настоятельно рекомендую эту статью о кэшировании и связанных с ним REDbot инструмент для проверки вашей конфигурации.

...