Загрузка файла работает с Chrome, но не в Firefox при загрузке сгенерированного файла golang
У меня есть простая служба REST golang / gin-gonic, которая предоставляет отчет в формате Excel по запросу /api/billing
, Когда запрашивающая сторона устанавливает заголовок принятия в 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 без каких-либо расширений и каких-либо изменений. То же самое происходит на 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
2 ответа
Я пытался решить проблему в течение нескольких дней. Однако я нашел виновника там, где этого не ожидал. Наконец, это было поведение приложения веб-интерфейса, так как у меня сложилось впечатление, что вызывается только ссылка, и я ошибся.
Тем не менее, я хотел бы отметить, что я могу успешно проверить, что браузер не заботится, если Content-Disposition
имеет '
, "
или вообще без цитирования.
Также джин / голанг выше работает как надо.
Спасибо всем за помощь.
Возможно, вам придется использовать двойные кавычки ("
) для имени файла Content Disposition вместо одинарных кавычек ('
):
extraHeaders := map[string]string{
"Content-Disposition": `attachment; filename="BillingReport.xlsx"`,
// Note the double quotes -------------------^------------------^
См. RFC 2616, раздел 19.5.1"Содержание-расположение":
Поле заголовка ответа Content-Disposition было предложено для исходного сервера, чтобы предложить имя файла по умолчанию, если пользователь запрашивает, чтобы содержимое было сохранено в файл...
content-disposition = "Content-Disposition" ":" disposition-type *( ";" disposition-parm ) ... filename-parm = "filename" "=" quoted-string
И раздел 2.2"Основные правила":
Строка текста анализируется как одно слово, если она заключена в кавычки с использованием двойных кавычек.
quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
RFC 6266 определяет дополнительные правила, но простое цитирование выше является самым простым.