我有简单的golang / gin-gonic REST服务,该服务可应/api/billing
的要求提供excel报告。当请求者将accept标头设置为application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
时,将提供Excel文件,否则将提供json。这段代码在Chrome和IE中可以正常运行,但在Firefox上却不能,而且我也不知道为什么。
在FF调试器中,我看到实际的内容已传输到浏览器,但是FF不向用户提供下载对话框。因此,对于用户而言,如果单击链接,则看起来什么也没有发生。
我已经检查了弹出窗口没有被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())
}
})
以下是与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
答案 0 :(得分:2)
您可能需要对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":
Content-Disposition响应标头字段已被提议作为原始服务器在用户请求将内容保存到文件时建议默认文件名的一种方法...
content-disposition = "Content-Disposition" ":" disposition-type *( ";" disposition-parm ) ... filename-parm = "filename" "=" quoted-string
如果使用双引号将文本字符串引用,则将其解析为单个单词。
quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
RFC 6266定义了其他规则,但上面的简单引用最简单。
答案 1 :(得分:0)
我尝试解决了几天的问题。但是,我找到了没想到的罪魁祸首。最终,这是前端应用程序的行为,因为我感觉这只是一个被调用的链接,我错了。
不过,我想指出的是,我可以成功验证浏览器是否在意Content-Disposition
是否具有'
,"
或根本没有引号。
上面的杜松子酒/ golang仍在正常工作。
感谢大家帮助我。