使用Django进行下载zip出现乱码

使用Django进行下载zip出现乱码
1 将文件进行压缩成zip


```python
def zip_dir(folder_path, images_path, vis_path, fig_path, chinese_path, english_path):
    name = str(time.time())
    folder_name = os.path.join(folder_path, "{0}.zip".format(name))
    file_list = []
    for i in range(len(images_path)):
        file_list.append(images_path[i])
        file_list.append(vis_path[i])
        file_list.append(fig_path[i])
        file_list.append(chinese_path[i])
        file_list.append(english_path[i])
    zf = zipfile.ZipFile(folder_name, "w", zipfile.zlib.DEFLATED)
    for tar in file_list:
        arc_name = tar[len(folder_path):]
        zf.write(tar, arc_name)
    zf.close()
    return folder_name, name

2 传输zip
def file_iterator(filename, chunk_size=512):
    with open(filename, 'rb') as f:
        while True:
            c = f.read(chunk_size)
            if c:
                yield c
            else:
                break
def download_sub(request):
    // 省略获得文件路径images_root, images_path, vis_path, fig_path, chinese_path, english_path等代码
    folder_name, name = zip_dir(images_root, images_path, vis_path, fig_path, chinese_path, english_path)
    response = StreamingHttpResponse(file_iterator(folder_name))
    response['Content-Type'] = 'application/octet-stream'
    response['Content-Disposition'] = 'attachment;filename="{0}.zip"'.format(name)
    return response

3 网页响应

img

img

img

参考GPT和自己的思路:

根据您提供的代码和截图,可以看出出现乱码的问题可能是因为您在下载时没有设置文件编码方式,可以尝试在响应头部增加一个charset字段来设置编码方式。

具体的修改方法如下:

response = StreamingHttpResponse(file_iterator(folder_name))
response['Content-Type'] = 'application/zip'
response['Content-Disposition'] = 'attachment;filename="{0}.zip"'.format(name)
response['charset'] = 'UTF-8'   # 增加charset字段,设置编码方式
return response

另外,建议在文件传输的过程中使用二进制模式,可以通过在open函数中设置参数"rb"来实现。

希望以上回答能够帮到您解决问题,如有疑问或者问题还未解决,请随时联系我。

参考GPT和自己的思路:

在你使用Django进行下载zip文件时出现乱码的情况,可能是由于以下原因:

  1. 文件名编码问题:当文件名包含非 ASCII 字符时,可能会出现编码问题。在 Django 中,可以使用 smart_str 函数对文件名进行编码,示例代码如下:

    from django.utils.encoding import smart_str
    
    response['Content-Disposition'] = 'attachment; filename="%s"' % smart_str(file_name)
    
  2. Content-Type 设置不正确:若响应的 Content-Type 设置不正确,客户端可能无法正确解码文件。应该将 Content-Type 设置为 'application/zip''application/octet-stream'

    response['Content-Type'] = 'application/zip'
    
  3. 函数 file_iterator 可能会导致文件流的截断或数据丢失。可以使用 FileWrapper 类简化代码,并避免这个问题:

    from django.core.servers.basehttp import FileWrapper
    
    # ...
    
    response = HttpResponse(FileWrapper(open(folder_name, 'rb')), content_type='application/zip')
    response['Content-Disposition'] = 'attachment; filename="%s"' % name + '.zip'
    
    return response
    

希望以上回答能够解决您的问题。