代码之家  ›  专栏  ›  技术社区  ›  Javier

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

  •  10
  • Javier  · 技术社区  · 16 年前

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

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

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

    3 回复  |  直到 16 年前
        1
  •  10
  •   Miroslav Bendik Vasil    7 年前

    如果你的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文件夹(MEDIAROT/high_rest)中的所有图像。对于其他静态文件,它的行为将与正常情况一样。请注意,这是一个对我有效的修改后的快速黑客。它可能会对安全产生影响,因此请谨慎使用。

        2
  •  4
  •   Andrew Kurinnyi    16 年前

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

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

    这个解决方案对我不起作用,因为我想同时拥有文件的直接链接(例如,这样用户就可以查看图像)和下载链接。

        3
  •  0
  •   Javier    12 年前

    我现在要做的是使用与“视图”不同的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"';
        }
    

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