пользовательские HTTP-заголовки для статических файлов с помощью Django
Вопрос
Я пишу банк изображений с помощью Django, и я хочу добавить кнопку для получения версии изображения в высоком разрешении (низкое разрешение показано на странице сведений).Если я поставлю просто <a>
перейдя по ссылке, браузер откроет изображение вместо того, чтобы загружать его.Добавление HTTP-заголовка, подобного:
Content-Disposition: attachment; filename="beach008.jpg"
работает, но поскольку это статический файл, я не хочу обрабатывать запрос с помощью Django.В настоящее время я использую NGINX для обслуживания статических файлов, а динамические страницы перенаправляются через FastCGI в процесс Django.Я подумываю об использовании NGINX add-header
команда, но может ли она установить filename="xx"
часть?.Или, может быть, есть какой-то способ обработать запрос в Django, но заставить NGINX обслуживать контент?
Решение
Если ваше приложение django проксируется nginx, вы можете использовать x-ускорение-перенаправление.Вам нужно передать специальный заголовок в вашем ответе, nginx перехватит это и начнет обслуживать файл, вы также можете передать Content-Disposition в том же ответе, чтобы принудительно загрузить.
Это решение хорошо, если вы хотите контролировать, какие пользователи получают доступ к этим файлам.
Вы также можете использовать подобную конфигурацию:
#files which need to be forced downloads
location /static/high_res/ {
root /project_root;
#don't ever send $request_filename in your response, it will expose your dir struct, use a quick regex hack to find just the filename
if ($request_filename ~* ^.*?/([^/]*?)$) {
set $filename $1;
}
#match images
if ($filename ~* ^.*?\.((jpg)|(png)|(gif))$) {
add_header Content-Disposition "attachment; filename=$filename";
}
}
location /static {
root /project_root;
}
Это приведет к принудительной загрузке всех изображений в некоторой папке high_res (MEDIAROOT / high_rest).А для других статических файлов он будет вести себя как обычно.Пожалуйста, обратите внимание, что это модифицированный быстрый взлом, который работает у меня.Это может иметь последствия для безопасности, поэтому используйте его с осторожностью.
Другие советы
Я написал простой декоратор для просмотра django.views.static.serve
Что работает для меня отлично. Р>
def serve_download(view_func):
def _wrapped_view_func(request, *args, **kwargs):
response = view_func(request, *args, **kwargs)
response['Content-Type'] = 'application/octet-stream';
import os.path
response['Content-Disposition'] = 'attachment; filename="%s"' % os.path.basename(kwargs['path'])
return response
return _wrapped_view_func
Также вы можете поиграть с mime-типами nginx
http://wiki.codemongers.com/NginxHttpCoreModule#types
Это решение не сработало для меня, потому что я хотел иметь как прямую ссылку на файл (чтобы пользователь мог просматривать изображения, например), так и ссылку для скачивания.
Что я делаю сейчас, так это использую другой URL для загрузки, чем для "просмотров", и добавляю имя файла в качестве аргумента URL:
обычная ссылка на СМИ: http://xx.com/media/images/lores/f_123123.jpg
ссылка для скачивания: http://xx.com/downs/hires/f_12323?beach008.jpg
и у nginx есть конфигурация, подобная этой:
location /downs/ {
root /var/www/nginx-attachment;
add_header Content-Disposition 'attachment; filename="$args"';
}
но мне действительно не нравится его запах.