Django+angula流式传输文件
最近项目对于下载文件的安全性有一定考虑,瞎敲了一天,感觉还凑合 —_—
环境:
python 3.5
django 1.10.3
后端-django的视图函数
作为一个熟练的面向百度工程师,文件流方式可以选择StreamingHttpResponse和FileResponse,在小文件上面并没有感觉出来太大的差别,如果大文件流式传输可能用FileResponse会更快一些。
因为项目的文件都是ZIP格式(不过测试的时候没有限制格式,excel等也是可以的)
from django.http import HttpResponse, StreamingHttpResponse
import os
class FileDownlad():
@login_required #限制登录访问
def post(self,request):
'''
返回流式文件对象
'''
file_path = os.path.join(self.root_dir,"webapp/static/data/match_file/{}.zip".format(file_name))
file = self.file_iterator(file_path)
response = StreamingHttpResponse(file)
response['content_type'] = "application/octet-stream"
response['Content-Disposition'] = 'attachment; filename={}.zip'.format(file_name)
return response
def file_iterator(self,file_name, chunk_size=512):
'''
用于形成二进制数据
'''
with open(file_name, 'rb') as f:
while True:
c = f.read(chunk_size)
if c:
yield c
else:
break
前端页面
<h3>
测试下载: <button class="test" ng-click="download()">点击下载</button>
</h3>
$scope.download = function () {
let param = {
"file_name": "test", #写死用作测试
}
$http.post('/service/application_view/file_download', param, {
// 指定headers
headers: {
'Content-Type': 'application/octet-stream' #
},
// 设置返回数据的类型–返回二进制数据
responseType: 'arraybuffer',
}).then(function (response) {
var b = new Blob([response.data], {type: 'application/zip'});
// 根据传入的参数b创建一个指向该参数对象的URL
var url = URL.createObjectURL(b);
var link = document.createElement('a');
// 设置导出的文件名
link.download = 'test.zip';
link.href = url;
// 点击获取文件
link.click();
}, function (response) {
});
}
BUG-ZIP文件显示损坏
在做这次的传输的时候,遇到了一个问题,就是下载下来的ZIP文件显示损坏。
最开始百思不得其解,确定好后端传过来的的数据是OK的之后就锁定到前端了,进行长时间的测试也没有测试出来啥问题
最后根据这个找到了解决办法
https://blog.csdn.net/qq_33592641/article/details/104991704
其实就是页面在解析的时候没有指定headers和设置返回的数据类型,导致ZIP文件报错
{
// 指定headers
headers: {
'Content-Type': 'application/octet-stream' #
},
// 设置返回数据的类型–返回二进制数据
responseType: 'arraybuffer',
}
欢迎指正!