使用Django的静态文件的自定义HTTP标头

时间:2008-11-04 19:36:14

标签: django http nginx

我正在用Django编写一个图像库,我想添加一个按钮来获得图像的高分辨率版本(低分辨率显示在详细信息页面中)。如果我只放一个<a>链接,浏览器将打开图像而不是下载它。添加HTTP标头,如:

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

有效,但由于它是一个静态文件,我不想用Django处理请求。目前,我正在使用NGINX来提供静态文件,动态页面通过FastCGI重定向到Django进程。我正在考虑使用NGINX add-header命令,但它可以设置filename="xx"部分吗?或者也许有一些方法来处理Django中的请求,但是让NGINX提供内容吗?

3 个答案:

答案 0 :(得分:10)

如果您的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)中的所有图像。而对于其他静态文件,它将表现得像平常一样。请注意,这是一个修改后的快速黑客,对我有用。它可能具有安全隐患,因此请谨慎使用。

答案 1 :(得分:4)

我为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

你也可以玩nginx mime-types

http://wiki.codemongers.com/NginxHttpCoreModule#types

此解决方案对我不起作用,因为我希望同时拥有该文件的直接链接(例如用户可以查看图像),并下载链接。

答案 2 :(得分:0)

我现在正在做的是使用不同的URL进行下载而不是“视图”,并将文件名添加为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"';
    }

但我真的不喜欢它的味道。