【问题标题】:Sending pdf as attachment causes undefined error in Chrome browser将 pdf 作为附件发送会导致 Chrome 浏览器出现未定义的错误
【发布时间】:2011-08-16 03:02:39
【问题描述】:

使用 Django,我正在从服务器发送一个 pdf 文件。如果我使用以下方式将其作为附件发送:

response['Content-Disposition'] = 'attachment; filename=test.pdf'

下载正常,但在 Chrome 控制台中出现错误:

GET http://12.345.678.09/vpas/?print_confirm=true undefined (undefined)

如果我在没有设置响应的 Content-Disposition 的情况下发送 pdf,则没有错误。这个错误的原因是什么,我该如何摆脱它?

这是 http(来自 Firefox - 无法从 Chrome 中获得更多详细信息):

http://12.345.678.09/vpas/?print_confirm=true&vpa_id_to_print=2355

GET /vpas/?print_confirm=true&vpa_id_to_print=2355 HTTP/1.1
Host: 12.345.678.09
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.17) Gecko/20110420 Firefox/3.6.17 GTB7.1 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Cookie: sessionid=fdabaccd2a731fd459cd5d6c3f5004f1
Cache-Control: max-age=0

HTTP/1.1 200 OK
Server: nginx/0.5.33
Date: Mon, 02 May 2011 00:59:48 GMT
Content-Type: application/pdf
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Cookie
Content-Disposition: attachment;
Set-Cookie: sessionid=fdabaccd2a731fd459cd5d6c3f5004f1; expires=Mon, 02-May-2011 01:59:48 GMT; Max-Age=3600; Path=/

这是我可以从 Chrome 获得的 http:

Request URL:http://12.345.678.09/vpas/?print_confirm=true&vpa_id_to_print=2355
Request Headers
Accept:application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
User-Agent:Mozilla/5.0 (Windows NT 5.1) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.60 Safari/534.24
Query String Parameters
print_confirm:true
vpa_id_to_print:2355

【问题讨论】:

  • 如果您可以添加 HTTP 跟踪,或者至少打印出浏览器接收到的标头字段,将会很有帮助。
  • 添加在上面。我不知道如何从 Chrome 中获取更详细的跟踪信息。
  • 跟踪没有显示 Content-Disposition 中的文件名参数...

标签: django http pdf google-chrome


【解决方案1】:
if not 'HTTP_USER_AGENT' in request.META or u'WebKit' in request.META['HTTP_USER_AGENT']:
    # Safari 3.0 and Chrome 2.0 accepts UTF-8 encoded string directly.
    filename_header = 'filename=%s' % original_filename.encode('utf-8')
elif u'MSIE' in request.META['HTTP_USER_AGENT']:
    try:
        original_filename.encode('ascii')
    except UnicodeEncodeError:
        original_filename = 'subtitles.' + h.file_type

    filename_header = 'filename=%s' % original_filename
else:
    # For others like Firefox, we follow RFC2231 (encoding extension in HTTP headers).
    filename_header = 'filename*=UTF-8\'\'%s' % iri_to_uri(original_filename.encode('utf-8'))

response['Content-Disposition'] = 'attachment; ' + filename_header

这是文件下载的示例。它是如此复杂,因为不同的浏览器以不同的方式处理“非 ascii”名称,这适用于 Chrome。

【讨论】:

  • Chrome 确实处理 RFC 2231,IE9 也是如此。唯一不支持它的是 Safari。
  • 谢谢。我试过 1) filename = 'print_confirm.pdf'.encode('utf-8')response['Content-Disposition'] = 'attachment; filename=%s' % filename 和 2) response['Content-Disposition'] = 'attachment; filename*=UTF-8\'\'%s' % iri_to_uri('print_confirm.pdf'.encode('utf-8')) 我在 Chrome 11 控制台中仍然未定义。
  • 也许问题出在其他地方。如果您根本不发送标头字段会发生什么?
  • 使用 Chrome 12.0.742.91 beta-m,我现在收到警告“资源解释为文档,但使用 MIME 类型应用程序/pdf 传输。”
【解决方案2】:
ctrl+shift+j

打开 chrome 控制台。

网络将具有标头信息。

【讨论】:

    【解决方案3】:

    我认为您的响应中的“transfer-encoding: chunked”HTTP 标头导致了问题。我在 ASP .NET Web 应用程序上遇到了类似的问题。 Chrome 问题记录在这里: http://code.google.com/p/chromium/issues/detail?id=83332

    尝试使用 PDF 文件附件的大小(以字节为单位)设置内容长度标题。我对 Django 一无所知,因此您可能还需要研究一种方法来显式抑制 transfer-encoding: chunked header。

    我还注意到,过早关闭 HTTP 响应(同样,这是 ASP .NET)对 Chrome 能够打开 PDF 文件有不利影响。

    【讨论】:

      【解决方案4】:

      在最近一次 Chrome 升级之后,我今天在渲染动态 pdf 时遇到了这个错误。以前,该代码在所有浏览器中都运行良好。

      我的解决方法是删除文件名中的所有嵌入空格和逗号。可能还有其他元字符要删除,但这为我的用户解决了问题。

      为了搜索引擎的利益,Chrome中出现的错误:

      从服务器收到重复的标头

      Error 349 (net::ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION)
      

      来自服务器的响应包含重复的标头。此问题通常是由于网站或代理配置错误造成的。只有网站或代理管理员可以解决此问题。

      【讨论】:

        【解决方案5】:

        该问题是由遵循正确 RFC 标准的 Chrome 16 引起的。

        您必须用双引号将文件名括起来。见http://code.google.com/p/chromium/issues/detail?id=103618

        在你的情况下,它会是......

        response['Content-Disposition'] = 'attachment; filename="test.pdf"'
        

        同样重要的是,您已经完成了,使用分号而不是逗号来分隔值。这可能会在 Chrome 中导致相同的结果

        【讨论】:

        • 令人印象深刻,你为我节省了至少 2 个研究错误小时。
        • 因为这是正确答案(也适用于我),我建议@mitch 将此答案标记为已接受。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-28
        • 1970-01-01
        • 1970-01-01
        • 2016-06-13
        • 2023-04-02
        • 1970-01-01
        相关资源
        最近更新 更多