Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

下载文件 Non-ASCII 文件名编码 #14

Closed
xmx opened this issue Dec 12, 2022 · 3 comments
Closed

下载文件 Non-ASCII 文件名编码 #14

xmx opened this issue Dec 12, 2022 · 3 comments

Comments

@xmx
Copy link
Contributor

xmx commented Dec 12, 2022

文件下载时,对于 Non-ASCII 的文件名,常见的 Go HTTP 框架几乎都使用 url.QueryEscape 编码:

ship 使用 url.QueryEscape

gin 使用 url.QueryEscape

beego 使用 url.PathEscape

iris 使用 url.QueryEscape

Go Frame 使用 url.QueryEscape

echo 未对 Non-ASCII 做处理

但是 url.QueryEscape 会将 空格转换+,如果文件名是 a b.txt,下载者看到的文件名就是 a+b.txt,虽然 url.QueryEscape 可以解决 Non-ASCII Header 乱码问题,但是我个人觉得并非最优解。对于 HTTP Header 我个人觉得这种场景正确处理方式应该是使用 mime.FormatMediaType 格式化。

基于上述问题,想请教下你对 Header 编码的看法。

参考 RFC2183

mime 代码示例:

// name: 文件名,例如:a b.txt
// dispositionType: inline 或 attachment
params := map[string]string{"filename": name}
disposition := mime.FormatMediaType(dispositionType, params)
c.res.Header().Set(HeaderContentDisposition, disposition)
@xgfone
Copy link
Owner

xgfone commented Dec 12, 2022

是的。

我发布了一个新的版本 v5.2.2,使用 mime.FormatMediaType 格式化应答头 Content-Disposition 的值:

params := map[string]string{"filename*": "utf-8''" + name}
disposition := mime.FormatMediaType(dispositionType, params)
c.res.Header().Set(HeaderContentDisposition, disposition)

使用 filename* 以代替 filename,是为了在 Header 中支持非标准的特殊字符。

@xmx
Copy link
Contributor Author

xmx commented Dec 13, 2022

感谢采纳!

mime.FormatMediaType 无需调用者添加 *utf-8'' 这些标识的,
它会判断自适应,如果是纯 ASCII 会正常输出,如果包含了 非 ASCII 就会编码 加 *添加 utf-8''

mime.FormatMediaType("attachment", map[string]string{"filename": "hi.txt"})
// 输出:attachment; filename=hi.txt

mime.FormatMediaType("attachment", map[string]string{"filename": "你好.txt"})
// 输出:attachment; filename*=utf-8''%E4%BD%A0%E5%A5%BD.txt

mime.FormatMediaType("attachment", map[string]string{"filename": "h i.txt"})
// 输出会加引号:attachment; filename="h i.txt"

@xgfone
Copy link
Owner

xgfone commented Dec 13, 2022

tks

@xgfone xgfone closed this as completed Feb 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants