Python django二进制文件下载在浏览器中损坏
我认为,在身份验证/权限之后,文件将作为保存在文件字段中的文件Python django二进制文件下载在浏览器中损坏,python,django,django-rest-framework,Python,Django,Django Rest Framework,我认为,在身份验证/权限之后,文件将作为保存在文件字段中的文件 from django.http import StreamingHttpResponse from rest_framework import viewsets from rest_framework.decorators import detail_route from wsgiref.util import FileWrapper import mimetypes from myapp.models import MyMode
from django.http import StreamingHttpResponse
from rest_framework import viewsets
from rest_framework.decorators import detail_route
from wsgiref.util import FileWrapper
import mimetypes
from myapp.models import MyModel
class ExampleViewSet(viewsets.ViewSet):
# Normal crud (retrive, list, etc.)
@detail_route(methods=['GET'])
def download(self, *args, **kwargs):
pk = self.request.parser_context['kwargs'].get('pk', None)
if pk is None:
raise exceptions.ParseError('no pk')
instance = MyModel.objects.get(pk=pk)
filename = instance.file_field.name.split('/')[-1]
mime = mimetypes.guess_type(filename)[0]
file = instance.file_field.file
response = StreamingHttpResponse(
FileWrapper(open(file, 'rb'), 10240))
response['Content-Type'] = "{0}; charset=utf-8".format(mime)
response['Content-Length'] = file.size
response[
'Content-Disposition'] = 'attachment; filename={0}'.format(filename)
return response
文件本身是用户先前上传的3.7MB jpeg文件。在上传目录下,文件大小为3.7MB,并且打开正确。
通过浏览器(Firefox或Chrome)下载时,文件大小为7.0MB且已损坏(没有正确的JPEG标题,该标题应以两个特定字节开头)。从curl或wget下载时,文件大小为3.7MB且打开正确
下面是curl使用curl-v对响应字段的输出
curl -v http://localhost:3000/api/school_admin/posters/7/download?token=ZXlKaGJHY2lPaUpJVXpVeE1pSXNJblI1Y0NJNklrcFhWQ0o5LmV5SndhR0Z6YUNJNkltSmpjbmx3ZEY5emFHRXlOVFlrSkRKaUpERXlKR2hzVlUxd2QyOWpTM1pMTnk1VlRuSXZPR1ZNVWs5aFJEVjBVbmR2V21FeVVGVlZiWGhxTTJWb1UzZFhla1JNU3k5RmFqZFRJaXdpY0hKdlptbHNaVjl3YXlJNk15d2laWGh3SWpveE5EY3lOalUyTWpFMGZRLmV6OGg5SWVwLUozYjdQcHJLVGJCZWlSSjJPN1JRdnItaFVuLVg0dmdLZGdtRGdQV0s2ZzkzdktialN2Uy1EVTVkM1hRc2hRZ3YxeVZmQlJhUDBBVlhB -o test.jpeg
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /api/school_admin/posters/7/download?token=ZXlKaGJHY2lPaUpJVXpVeE1pSXNJblI1Y0NJNklrcFhWQ0o5LmV5SndhR0Z6YUNJNkltSmpjbmx3ZEY5emFHRXlOVFlrSkRKaUpERXlKR2hzVlUxd2QyOWpTM1pMTnk1VlRuSXZPR1ZNVWs5aFJEVjBVbmR2V21FeVVGVlZiWGhxTTJWb1UzZFhla1JNU3k5RmFqZFRJaXdpY0hKdlptbHNaVjl3YXlJNk15d2laWGh3SWpveE5EY3lOalUyTWpFMGZRLmV6OGg5SWVwLUozYjdQcHJLVGJCZWlSSjJPN1JRdnItaFVuLVg0dmdLZGdtRGdQV0s2ZzkzdktialN2Uy1EVTVkM1hRc2hRZ3YxeVZmQlJhUDBBVlhB HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< date: Mon, 29 Aug 2016 18:31:30 GMT
< server: WSGIServer/0.2 CPython/3.4.3
< allow: GET, DELETE, HEAD, OPTIONS
< content-type: image/jpeg; charset=utf-8
< vary: Accept
< content-length: 3947925
< content-disposition: attachment; filename=poster_28F7bdD4caAbCc583831c9E7C9baDaEC88Ecbde6FBAA6aE71cAdC09fd8EFCF7BD515155bec1C3FC6f01c6FEf5Ba76e41952E_Colosseum_in_Rome_Italy_-_April_2007.jpg
< x-frame-options: SAMEORIGIN
< via: 1.1 fedora
< Connection: keep-alive
<
{ [15913 bytes data]
100 3855k 100 3855k 0 0 141M 0 --:--:-- --:--:-- --:--:-- 144M
* Connection #0 to host localhost left intact
curl-vhttp://localhost:3000/api/school_admin/posters/7/download?token=ZXlKaGJHY2lPaUpJVXpVeE1pSXNJblI1Y0NJNklrcFhWQ0o5LmV5SndhR0Z6YUNJNkltSmpjbmx3ZEY5emFHRXlOVFlrSkRKaUpERXlKR2hzVlUxd2QyOWpTM1pMTnk1VlRuSXZPR1ZNVWs5aFJEVjBVbmR2V21FeVVGVlZiWGhxTTJWb1UzZFhla1JNU3k5RmFqZFRJaXdpY0hKdlptbHNaVjl3YXlJNk15d2laWGh3SWpveE5EY3lOalUyTWpFMGZRLmV6OGg5SWVwLUozYjdQcHJLVGJCZWLSSJJPN1JRDNITAFVULVG0DMDLZGDRGDQV0S2ZZKZDKTIALN2UY1EVTVKM1HRC2HRZ3YXEVZMQLJHUDBVLHB-o test.jpeg
%总接收百分比%x平均速度时间电流
数据加载上载总左速度
0 0 0 0 0 0 0--:-:-:-:---:-:---0*正在尝试127.0.0.1。。。
*已连接到本地主机(127.0.0.1)端口3000(#0)
>得到/api/学校管理员/海报/7/下载?token=zxlkagjhy2lpapujvxpveee1psxnjbli1njnklrcfhwq0o5lmv5sndhr0z6yunkltsmpjbmx3zey5emfhrxlovflkrkauperxlkr2hzvlusxpr1znvws5afjevjbmr2v21fevvlgzwgwgwgwgwgwg5rmzfjjjjjjdpy0hk1hkjjjjjjjjjjjjjjjjjwwwf1hk1hk1hkjjjjjjjjjjjwwwzzzzzzzzwjjjvzwg5wg5vzzzzzzzzwjjvzzzzzzzwjjjjjjljjvzzzzVULVG0DMDLZGDRGDQV0S2ZZKZDKTIALN2UY1EVTKM1HRC2HRZ3YXEVZMQLJHUDBVLHB HTTP/1.1
>主机:localhost:3000
>用户代理:curl/7.43.0
>接受:*/*
>
这通常是在以ASCII文件传输类型通过FTP上传文件/数据时引起的。
“ASCII传输类型”将文件作为常规文本文件传输,因此没有问题。
但是,“二进制传输类型”将以二进制模式传输数据,该模式将文件作为二进制数据而不是文本数据处理。
将FTP客户端设置为二进制将防止文件在FTP传输过程中损坏。请参阅以下有关如何将FTP程序切换为二进制的内容
在这里,您应该尝试使用ASCII格式的二进制数据。当我使用nginx+uwsgi时,问题得到了解决。我认为这与django的runserver拒绝添加的一些“逐跳”标题有关,如果我手动添加这些标题,则会出现错误。这些标题通常与反向代理有关。文件是通过http而不是ftp上传的,b但即使是这样,curl和wget不会面临与浏览器相同的问题吗?上传文件夹中的文件也会被破坏吗?