Content-Disposition 中文编码

今天在使用koa下载文件的时候,一直抱错'invalid charactor',关键是明明测试都没得问题的,郁闷了老半天

this.set({"Content-disposition": `attachment; filename=test.xlsx`});
this.set({'Content-type': 'application/vnd.ms-excel'});
this.body = buffer;

后来返现测试上用的是test.xlsx,而生产上是动态的文件名,有些时候会是中文,所以基本上肯定了是header中编码的问题。

content-disposition

content-disposition是mime协议的扩展,而mime协议指示mime用户代理如何显示附加的文件,content-disposition其实可以控制用户请求所得到内容为一个文件时为其提供一个文件名字,文件可以是直接在浏览器上显示或文件下载。

注:disposition-type 文件的下载方式, inline直接在浏览器中打开,attachment以附件形式

content-disposition中的编码

http header中有content-type来指定body的编码,但是header中却没有,如果header中携带里信息却没有编码(默认是ACSII码),那浏览器是无法识别header中信息的,可能就会导致某些问题。

2010年 RFC 5987 发布,正式规定了 HTTP Header 中多语言编码的处理方式,应当采用类似 MIME 扩展的 parameter*=charset'lang'value 的格式,但是其中 value 应根据 RFC 3986 Section 2.1 使用百分号进行编码,并且规定浏览器至少应该支持 ASCII 和 UTF-8 。

例如

Content-Disposition: attachment;filename="encoded_text";filename*=utf-8''encoded_text

对于ascii码采用最简单的filename='name.text'无需编码,对于可能含有非acss码(通常是UTF-8)建议使用上面的形式

针对上面的问题我自己的代码如下

this.set({"Content-disposition": `attachment; filename*=UTF-8''${urlencode(name)}.xlsx`});
this.set({'Content-type': 'application/vnd.ms-excel'});
this.body = buffer;

转载于:https://my.oschina.net/u/1249401/blog/810440

### 解决 HTTP 响应头 Content-Disposition 中文文件名乱码问题 对于 HTTP 响应头 `Content-Disposition` 字段中出现的中文文件名乱码问题,解决方案主要依赖于正确编码文件名称并遵循 RFC 6266 和 RFC 5987 的规定。 当服务器返回带有附件的内容给客户端时,在响应头部加入适当格式化的 `Content-Disposition` 是必要的。为了确保不同浏览器都能正常解析含有非ASCII字符(如汉字)的名字,推荐采用如下方式构建该头部: ```plaintext Content-Disposition: attachment; filename="encoded-filename"; filename*=UTF-8''encoded-filename ``` 其中 `filename*=` 后面的部分应当按照 URI 组件编码规则处理过的字符串表示形式[^1]。具体实现方法取决于所使用的编程语言及其框架特性;以下是 Python Flask 应用程序的一个例子来说明这一点: ```python from urllib.parse import quote from flask import make_response def send_file_with_chinese_name(file_path, original_filename): response = make_response(open(file_path, 'rb').read()) # 使用 UTF-8 编码和 URL 百分号转义序列对文件名进行编码 encoded_filename = quote(original_filename) disposition_value = f'attachment; filename="{original_filename}"; filename*=UTF-8\'\'{encoded_filename}' response.headers['Content-Type'] = 'application/octet-stream' response.headers['Content-Disposition'] = disposition_value return response ``` 上述代码片段展示了如何创建一个包含正确编码后的中文文件名作为下载链接的一部分,并将其附加到 HTTP 响应对象上的过程。通过这种方式可以有效避免因字符集差异而导致的目标文件保存失败或显示异常的情况发生。 另外需要注意的是,如果是在前端使用 Axios 进行文件下载操作,则应该设置合适的 `responseType` 参数以确保能够正确读取二进制流而不受编码影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值