我正在用Django编写一个图像库,我想添加一个button来获取图像的高分辨率版本(低分辨率显示在详细信息页面中)。 如果我只放一个<a>
链接,浏览器将打开图片而不是下载它。 添加一个HTTP标头,如:
Content-Disposition: attachment; filename="beach008.jpg"
工作,但由于它是一个静态文件,我不想用Django处理请求。 目前,我正在使用NGINX提供静态文件,dynamic页面通过FastCGIredirect到Django进程。 我正在考虑使用NGINX的add-header
命令,但它可以设置filename="xx"
部分? 或者也许有一些方法来处理在Django的请求,但使NGINX服务内容?
如果您的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文件夹中的所有图像(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
你也可以玩nginx mime-types
http://wiki.codemongers.com/NginxHttpCoremodulee#types
这个解决方案对我不起作用,因为我想直接链接文件(例如用户可以查看图像),并下载链接。
我现在正在做的是使用一个不同的网址下载比“视图”,并添加文件名作为URL arg:
通常的媒体链接: http://img.zgserver.com/django/f
: http://img.zgserver.com/django/f
下载链接: http://img.zgserver.com/django/f_12323beach008.jpg
: http://img.zgserver.com/django/f_12323beach008.jpg
和nginx有这样的配置:
location /downs/ { root /var/www/nginx-attachment; add_header Content-Disposition 'attachment; filename="$args"'; }
但我真的不喜欢它的气味。