下载 golang 生成的文件时,文件下载适用于 Chrome 但不适用于 Firefox
File Download works with Chrome but not in Firefox when downloading golang generated file
我有简单的 golang/gin-gonic REST 服务,可根据 /api/billing
的请求提供 excel 报告。当请求者将接受 header 设置为 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
时,将提供 Excel 文件,否则 json。此代码在 Chrome 和 IE 中运行良好,但在 Firefox 中运行不正常,我不知道为什么。
在 FF 调试器中,我看到实际内容已传输到浏览器,但 FF 不向用户提供下载对话框。因此,对于用户来说,如果他点击 link,就好像什么都没有发生一样。
我已经检查过弹出窗口没有被 FF 阻止,我还禁用了其他安全功能 https://support.mozilla.org/1/firefox/62.0.2/Darwin/de/phishing-malware 以防万一。我还重新安装了普通 FF,没有任何扩展和任何更改。 windows.
上的 FF 也会发生同样的情况
r.GET("/api/billing", func(c *gin.Context) {
if c.GetHeader("Accept") == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" {
b := api.GetBillingReportExcel()
extraHeaders := map[string]string{
"Content-Disposition": "attachment;filename='BillingReport.xlsx'",
"Content-Transfer-Encoding": "binary",
"Content-Description": "Excel Billing Report",
}
c.DataFromReader(200, int64(b.Len()),"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",&b,extraHeaders)
}else {
billingTenants, _ := cache.Get(c.Request.RequestURI)
c.JSON(200, GetBillingData())
}
})
这是请求 header它们对于 FF 和 Chrome
是相同的
HTTP 请求:
Host: localhost:8081
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:61.0) Gecko/20100101 Firefox/61.0
Accept: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://localhost:8081/
Connection: keep-alive
回应
HTTP/1.1 200 OK
X-Powered-By: Express
content-description: Excel Billing Report
content-disposition: attachment; filename='BillingReport.xlsx'
content-length: 11397
content-transfer-encoding: binary
content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
date: Tue, 25 Sep 2018 12:17:41 GMT
您可能需要为 Content Disposition filename 使用双引号 ("
) 而不是单引号 ('
):
extraHeaders := map[string]string{
"Content-Disposition": `attachment; filename="BillingReport.xlsx"`,
// Note the double quotes -------------------^------------------^
参见RFC 2616 Section 19.5.1 "Content-Disposition":
The Content-Disposition response-header field has been proposed as a means for the origin server to suggest a default filename if the user requests that the content is saved to a file...
content-disposition = "Content-Disposition" ":"
disposition-type *( ";" disposition-parm )
...
filename-parm = "filename" "=" quoted-string
A string of text is parsed as a single word if it is quoted using double-quote marks.
quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
RFC 6266 定义了额外的规则,但上面的简单引用是最简单的。
我尝试了几天来解决这个问题。但是我在我没想到的地方找到了罪魁祸首。它最终是前端应用程序的行为,因为我的印象是它只是一个被调用的 link 而我错了。
但是我想指出,我可以成功验证浏览器不关心 Content-Disposition
是否有 '
、"
或根本没有引号。
上面的 gin/golang 也正常工作。
感谢大家帮助我。
我有简单的 golang/gin-gonic REST 服务,可根据 /api/billing
的请求提供 excel 报告。当请求者将接受 header 设置为 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
时,将提供 Excel 文件,否则 json。此代码在 Chrome 和 IE 中运行良好,但在 Firefox 中运行不正常,我不知道为什么。
在 FF 调试器中,我看到实际内容已传输到浏览器,但 FF 不向用户提供下载对话框。因此,对于用户来说,如果他点击 link,就好像什么都没有发生一样。
我已经检查过弹出窗口没有被 FF 阻止,我还禁用了其他安全功能 https://support.mozilla.org/1/firefox/62.0.2/Darwin/de/phishing-malware 以防万一。我还重新安装了普通 FF,没有任何扩展和任何更改。 windows.
上的 FF 也会发生同样的情况r.GET("/api/billing", func(c *gin.Context) {
if c.GetHeader("Accept") == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" {
b := api.GetBillingReportExcel()
extraHeaders := map[string]string{
"Content-Disposition": "attachment;filename='BillingReport.xlsx'",
"Content-Transfer-Encoding": "binary",
"Content-Description": "Excel Billing Report",
}
c.DataFromReader(200, int64(b.Len()),"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",&b,extraHeaders)
}else {
billingTenants, _ := cache.Get(c.Request.RequestURI)
c.JSON(200, GetBillingData())
}
})
这是请求 header它们对于 FF 和 Chrome
是相同的HTTP 请求:
Host: localhost:8081
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:61.0) Gecko/20100101 Firefox/61.0
Accept: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://localhost:8081/
Connection: keep-alive
回应
HTTP/1.1 200 OK
X-Powered-By: Express
content-description: Excel Billing Report
content-disposition: attachment; filename='BillingReport.xlsx'
content-length: 11397
content-transfer-encoding: binary
content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
date: Tue, 25 Sep 2018 12:17:41 GMT
您可能需要为 Content Disposition filename 使用双引号 ("
) 而不是单引号 ('
):
extraHeaders := map[string]string{
"Content-Disposition": `attachment; filename="BillingReport.xlsx"`,
// Note the double quotes -------------------^------------------^
参见RFC 2616 Section 19.5.1 "Content-Disposition":
The Content-Disposition response-header field has been proposed as a means for the origin server to suggest a default filename if the user requests that the content is saved to a file...
content-disposition = "Content-Disposition" ":"
disposition-type *( ";" disposition-parm )
...
filename-parm = "filename" "=" quoted-string
A string of text is parsed as a single word if it is quoted using double-quote marks.
quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
RFC 6266 定义了额外的规则,但上面的简单引用是最简单的。
我尝试了几天来解决这个问题。但是我在我没想到的地方找到了罪魁祸首。它最终是前端应用程序的行为,因为我的印象是它只是一个被调用的 link 而我错了。
但是我想指出,我可以成功验证浏览器不关心 Content-Disposition
是否有 '
、"
或根本没有引号。
上面的 gin/golang 也正常工作。
感谢大家帮助我。