我的一个 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等浏览器.
请问有什么办法可以解决这个题呢? 比如在请求里增加某些参数?
1
em70 2015-02-26 07:54:48 +08:00 via Android
这个问题和文件名编码有关,都是文件名是中文的时候出现吧,有的浏览器默认编码是gbk不是自动选择编码就会出问题,输出前设置一下页面编码强制为utf8即可
|
2
jasontse 2015-02-26 07:56:18 +08:00 via Android
文件本身是多大,考虑是不是防盗链之类的问题。
|
3
cxh116 2015-02-26 08:31:10 +08:00
文件大的话可以考虑用nginx或apache的 X-Sendfile特性,django只告诉nginx返回什么文件,发送文件由nginx完成.
一个下载就占用一个django的进程,如果你只开了10个进程,10个人同时来下载,估计就把后面的人的访问全部阻塞掉了,就有可能就直接返回网关超时之类的错. 在手机移动网络这样慢速环境,一个5kb的东西也许下载一分钟也不一定 |
4
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 |
5
guoqiao OP @cxh116 我曾经尝试过使用 nginx 的X-Sendfile, 但是根据搜索到的教程都没有成功, 就放弃了.
请问你有示例代码吗? |
6
cxh116 2015-02-26 09:24:59 +08:00 3
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 |
8
n37r06u3 2015-02-26 22:13:44 +08:00 1
response = HttpResponse(mimetype='application/force-download')
response['Content-Disposition'] = 'attachment; filename=%s' % smart_str(file_name) response['X-Sendfile'] = smart_str(path_to_file) 。。。 |
9
sammo 2015-02-26 23:41:55 +08:00
在 readfree.me 有同样状况,即 点下载后, 得到的是一个只有几十 K 的网页文件, 而不是文件本身. 状况出现在用 360 浏览器时
|
10
guoqiao OP |