2008-11-04 116 views
9

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

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

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

回答

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; 
     } 

     if ($filename ~* ^.*?\.(jpg)|(png)|(gif)$){ 
         add_header Content-Disposition "attachment; filename=$filename"; 
        } 
     } 

    location /static { 
     root /project_root; 
    } 

这将迫使一些high_res文件夹(介质根/ high_rest)所有图像下载。而对于其他静态文件,它将表现得像正常一样。请注意,这是一个修改后的快速入侵,适合我。它可能有安全隐患,所以谨慎使用它。

+0

太棒了!正是我所期待的。 – Javier 2008-12-22 17:48:07

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

​​

该解决方案并没有为我工作玩,因为我想有直接联系的文件(这样用户可以查看图像,例如)和下载链接。

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"'; 
    } 

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