flask+gunicorn中文文件下载报错问题及解决

本文详细介绍了在使用Flask框架时,如何解决中文文件名在下载过程中出现的编码错误问题,包括对响应头的设置和使用urllib.parse.quote进行编码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

导言

问题源起与一个静态文件下载的接口:

from flask import Flask, current_app
app = Flask(__name__)

@app.route('/file_name')
def file_download(file_name):
    return send_from_directory(current_app.root_path, file_name)

当file_name中有中文的时候出现内部错误提示:

UnicodeEncodeError: 'latin-1' codec can't encode characters in position 46-47: ordinal not in range(256)

故障排解

查找发现发现是中文编码出了问题,需要对响应头进行设置: 参考

from flask import Flask, current_app,send_from_directory
app = Flask(__name__)


@app.route('/file_name')
def file_download(file_name):
    res = make_response(send_from_directory(current_app.root_path, file_name, as_attachment=True, conditional=True))
    res.headers["Content-Disposition"] = 'attachment; filename*="utf-8\'\'{}"'.format(file_name.encode().decode('latin-1'))
    return res

这下在本地运行终于可以正常下载了。但放到服务器上用gunicorn部署的时候又出现了问题:

Traceback (most recent call last):
  File "/home/dev/backend/backcode/convert-excel/venv/lib/python3.5/site-packages/gunicorn/workers/sync.py", line 135, in handle
    self.handle_request(listener, req, client, addr)
  File "/home/dev/backend/backcode/convert-excel/venv/lib/python3.5/site-packages/gunicorn/workers/sync.py", line 179, in handle_request
    resp.write_file(respiter)
  File "/home/dev/backend/backcode/convert-excel/venv/lib/python3.5/site-packages/gunicorn/http/wsgi.py", line 411, in write_file
    if not self.sendfile(respiter):
  File "/home/dev/backend/backcode/convert-excel/venv/lib/python3.5/site-packages/gunicorn/http/wsgi.py", line 390, in sendfile
    self.send_headers()
  File "/home/dev/backend/backcode/convert-excel/venv/lib/python3.5/site-packages/gunicorn/http/wsgi.py", line 337, in send_headers
    util.write(self.sock, util.to_bytestring(header_str, "ascii"))
  File "/home/dev/backend/backcode/convert-excel/venv/lib/python3.5/site-packages/gunicorn/util.py", line 509, in to_bytestring
    return value.encode(encoding)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 152-157: ordinal not in range(128)

经过一番查找,又找到了这个网址,参考里面的回答,又将代码改成下面这种形式:

from urllib.parse import quote

from flask import Flask, current_app,send_from_directory

app = Flask(__name__)

@app.route('/file_name')
def file_download(file_name):
    res = make_response(send_from_directory(current_app.root_path, file_name, as_attachment=True, conditional=True))
    res.headers["Content-Disposition"] = 'attachment; filename={}"'.format(quote(file_name))
    return res

这下终于成功下载中文文件名的文件了。

转载于:https://www.cnblogs.com/zhangjpn/p/8762729.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值