пользовательские заголовки HTTP для статических файлов с Django - PullRequest
9 голосов
/ 04 ноября 2008

Я пишу банк изображений с помощью Django и хочу добавить кнопку, чтобы получить версию изображения в высоком разрешении (низкое разрешение показано на странице сведений). Если я добавлю только ссылку <a>, браузер откроет изображение вместо его загрузки. Добавление заголовка HTTP, например:

Content-Disposition: attachment; filename="beach008.jpg"

работает, но так как это статический файл, я не хочу обрабатывать запрос с помощью Django. В настоящее время я использую NGINX для обслуживания статических файлов, а динамические страницы перенаправляются через FastCGI в процесс Django. Я думаю об использовании команды NGINX add-header, но может ли она установить часть filename="xx" ?. Или, может быть, есть какой-то способ обработать запрос в Django, но заставить NGINX обслуживать контент?

Ответы [ 3 ]

10 голосов
/ 22 декабря 2008

Если ваше приложение django проксируется с помощью nginx, вы можете использовать x-accell-redirect . Вам нужно передать специальный заголовок в вашем ответе, 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). А для других статических файлов он будет вести себя как обычно. Обратите внимание, что это модифицированный быстрый взлом, который работает для меня. Это может иметь последствия для безопасности, поэтому используйте его с осторожностью.

4 голосов
/ 05 ноября 2008

Я написал простой декоратор, для django.views.static.serve view

Что работает для меня отлично.

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

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

0 голосов
/ 05 ноября 2008

Что я делаю сейчас, так это использую для загрузки другой URL, чем для «views», и добавляю имя файла в качестве URL arg:

обычная медиа-ссылка: 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"';
    }

но мне действительно не нравится его запах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...