今天聊一聊下载文件被损坏(没有下载完)的问题

昨天,公司的项目中有个文档需要下载,但是下载失败,浏览器给出的错误是“失败-网络错误”。然后就去定位错误,但是发现代码没问题,在本地可以下载成功,一放在服务器就出问题,每次遇到这种问题就很头痛,没办法,继续找问题。然后我就按照这个错误的提示去查了查资料,惊奇的发现没有。。。。。。最后也不知道找了多少次,终于是找到了一个和这个错误有关的文章。这个文章说的是这个错误是谷歌浏览器新版本的原因,需要在响应头里添加Content-Length属性,来限制流的长度。终于找到一个相关的文章,然后我就迫不及待的去试试,结果就是失败,而且在本地测试的时候下载的文件都是损坏的。WHY?搞到这个时候我懵了,我加了个属性,然后文件就被损坏了???纠结好长时间之后,发现是不是Content-Length这个属性的值是不是设置的有点小了呢,然后我就改大一点,我就改的比我的文件稍大一点,然后本地测试可以了,此时,我心想这次应该就ok了吧,然后再放到服务器测试的时候,可以下载了,但是致命的问题来了,一打开文件,文件里的图片都没有,一看文件大小,完全不一样,真的是无奈了。然后我就打算在群里问一下群里的大佬,有一个大佬说让我用md5来检验文件的一致性,看看服务器的文件和下载的文件是否一致,但当时已经回家了,也没办法测试,所以今天一到公司就试试这个方法,然后就测出服务器的文件是没问题,下载的文件并没有下载完。然后我就打算查查怎么才能完整的下载文件的时候,偶然看见,django项目部署到服务器的时候,一般下载都会通过nginx来控制的,然后我就试着搜搜nginx下载文件这个方面,嘿,还真让我找到了,说的是下载文件时,nginx会先从后端拿到文件并缓冲到本地,然后响应给客服端,但是这个缓冲区的大小时有限制的,如果超过了这个限制,那么缓冲区满了的话,其他的文件内容就无法读取,然后就导致下载的文件不完整。感觉一切都可以说得通了,然后就让负责服务器的小伙伴修改了一下nginx的配置,经测试,完美解决。

下面是我的下载文件函数的代码:

#缓冲区 生成一个迭代器
    def file_iterator(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
  
     #找到文件夹下面的文件  是一个列表
     files = os.listdir(os.path.join(BASE_DIR, 'media/files'))
     the_file_name = files[0]
     response = FileResponse(file_iterator('media/files/'+the_file_name))
     response['Content-Type'] = 'application/octet-stream'
     response['Content-Disposition'] = 'attachment;filename="{0}"'.format(escape_uri_path(the_file_name))
     return response

参考资料:

https://www.aliyun.com/jiaocheng/336844.html

https://blog.csdn.net/jianxing11/article/details/81560379

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值