10

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

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

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

4

3 回答 3

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

于 2008-12-22T15:06:40.363 回答
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

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

于 2008-11-04T21:40:16.760 回答
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"';
    }

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

于 2008-11-04T22:09:11.117 回答