Загрузка файла работает с Chrome, но не в Firefox при загрузке сгенерированного файла golang - PullRequest
0 голосов
/ 25 сентября 2018

У меня есть простая служба 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 в Windows.

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 ]

0 голосов
/ 28 сентября 2018

Я пытался решить проблему в течение нескольких дней.Однако я нашел виновника там, где этого не ожидал.Наконец, это было поведение приложения веб-интерфейса, так как у меня сложилось впечатление, что это просто ссылка, которая вызывается, и я ошибся.

Однако я хотел отметить, что могу успешно убедиться, что браузер невсе равно, если у Content-Disposition есть ', " или вообще нет кавычек.

Также приведенный выше джин / голанг работает как надо.

Спасибо всем за помощьвне.

0 голосов
/ 25 сентября 2018

Возможно, вам придется использовать двойные кавычки (") для имени файла размещения содержимого вместо одинарных кавычек ('):

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 = "Content-Disposition" ":"
                          disposition-type *( ";" disposition-parm )
    ...
    filename-parm = "filename" "=" quoted-string

и Раздел 2.2 "Основные правила" :

Строкатекст анализируется как одно слово, если он заключен в кавычки с использованием двойных кавычек.

  quoted-string  = ( <"> *(qdtext | quoted-pair ) <"> )

RFC 6266 определяет дополнительные правила, но приведенное выше простое цитирование является самым простым.

...