Python 中如何正确生成文件下载请求?

2015-02-26 07:21:21 +08:00
 guoqiao

我的一个 Django 项目, 需要控制用户下载文件的权限. 目前生成下载请求的代码大致如下:

response = HttpResponse(data, content_type='application/octet-stream')
content = 'attachment; filename=%s' % (filename,)
response['Content-Disposition'] = content
return response

在 Chrome, Firefox 以及 Safari 这些主流浏览器上都可以正常工作.
但比较奇怪的是, 有很多用户反馈说点下载后, 得到的是一个只有几十 K 的网页文件, 而不是文件本身. 这些用户大多使用QQ, UC, 360等浏览器.

请问有什么办法可以解决这个题呢? 比如在请求里增加某些参数?

3582 次点击
所在节点    Python
11 条回复
em70
2015-02-26 07:54:48 +08:00
这个问题和文件名编码有关,都是文件名是中文的时候出现吧,有的浏览器默认编码是gbk不是自动选择编码就会出问题,输出前设置一下页面编码强制为utf8即可
jasontse
2015-02-26 07:56:18 +08:00
文件本身是多大,考虑是不是防盗链之类的问题。
cxh116
2015-02-26 08:31:10 +08:00
文件大的话可以考虑用nginx或apache的 X-Sendfile特性,django只告诉nginx返回什么文件,发送文件由nginx完成.

一个下载就占用一个django的进程,如果你只开了10个进程,10个人同时来下载,估计就把后面的人的访问全部阻塞掉了,就有可能就直接返回网关超时之类的错. 在手机移动网络这样慢速环境,一个5kb的东西也许下载一分钟也不一定
Septembers
2015-02-26 08:53:24 +08:00
检查日志 来自QQ, UC, 360的用户有带用户标识没(SessionID, Cookies, etc)
看描述我觉得是权限检查不通过导致的

对鉴权失败的响应423 这样比较合理

see http://tools.ietf.org/html/rfc4918#section-11.3
guoqiao
2015-02-26 09:02:31 +08:00
@cxh116 我曾经尝试过使用 nginx 的X-Sendfile, 但是根据搜索到的教程都没有成功, 就放弃了.
请问你有示例代码吗?
cxh116
2015-02-26 09:24:59 +08:00
nginx需要开启sendfile特性才有用

http://nginx.org/cn/docs/http/ngx_http_core_module.html#sendfile
```
语法: sendfile on | off;
默认值:
sendfile off;
上下文: http, server, location, if in location
```
之后设置http response header
https://djangosnippets.org/snippets/2728/
或直接使用第三方包
https://github.com/johnsensible/django-sendfile
guoqiao
2015-02-26 09:50:41 +08:00
@cxh116 你的回答都是干货, 直接解决了我的困扰. 非常感谢!
n37r06u3
2015-02-26 22:13:44 +08:00
response = HttpResponse(mimetype='application/force-download')
response['Content-Disposition'] = 'attachment; filename=%s' % smart_str(file_name)
response['X-Sendfile'] = smart_str(path_to_file)
。。。
sammo
2015-02-26 23:41:55 +08:00
readfree.me 有同样状况,即 点下载后, 得到的是一个只有几十 K 的网页文件, 而不是文件本身. 状况出现在用 360 浏览器时
guoqiao
2015-02-27 05:58:30 +08:00
@n37r06u3
force-download 并不是标准的MIME类型, 而是一种只有少量浏览器支持的 hack.
我试过用它, 但是在一些浏览器例如360上, 还是不起作用.
guoqiao
2015-02-27 05:59:53 +08:00
@sammo 我现在测试的结果是:
360浏览器 OK, 但 QQ 浏览器依然有问题.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/172830

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX