【问题标题】:Chrome and Firefox are not displaying most PDF documents in an iframeChrome 和 Firefox 不在 iframe 中显示大多数 PDF 文档
【发布时间】:2011-11-11 00:40:20
【问题描述】:

我运行的是 64 位的 Windows 7。我最近更新了我的操作系统以安装最新的更新。从那时起,大多数 PDF 文档已停止在我的程序中呈现。我的程序想要在单独的 iFrame 中显示 PDF 文档。我通过获取 PDF 文档的 URL 并设置 window.frames['docview'].location = url; 来做到这一点。在大多数情况下,iframe 视图保持空白(如果之前在那里显示过某些内容,则清除)。如果我使用相同的 URL 并在新选项卡或窗口中打开它,它会呈现正常。

当它无法在我的 iframe 中呈现时,我会在 Chrome 控制台中看到以下消息:

Resource interpreted as Document but transferred with MIME type application/pdf.

Firefox 不会在其错误控制台或 FireBug 控制台中提供任何类型的消息。

我无法控制 PDF 文件的来源,因此我无法更改它们的标题信息。

奇怪的是,有些文件确实可以正确加载。

查看 Chrome 中的网络请求,我看到(例如)加载失败的文档:

Request URL:http://es.csiro.au/pubs/paradis_mdm03.pdf
Request Method:GET
Status Code:200 OK

Request Headers
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Host:es.csiro.au
Referer:http://querium.fxpal.net:8080/querium/ui/query?searcherId=2&compact=true&sidx=rank&topicId=2&queryId=1&lastEventId=1490893682130103&highlight=undefined
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.220 Safari/535.1

Response Headers
Accept-Ranges:bytes
Connection:Keep-Alive
Content-Length:71764
Content-Type:application/pdf
Date:Tue, 06 Sep 2011 04:59:26 GMT
ETag:"1f48c8-11854-43e4ee482ef40"
Keep-Alive:timeout=15, max=100
Last-Modified:Wed, 07 Nov 2007 04:07:49 GMT
Server:Apache/2.0.55 (Ubuntu) PHP/5.1.2 mod_ssl/2.0.55 OpenSSL/0.9.8a

从单独的选项卡(文档在其中呈现)打开时,我得到以下信息:

Request URL:http://es.csiro.au/pubs/paradis_mdm03.pdf
Request Method:GET
Status Code:304 Not Modified

Request Headers
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Host:es.csiro.au
If-Modified-Since:Wed, 07 Nov 2007 04:07:49 GMT
If-None-Match:"1f48c8-11854-43e4ee482ef40"
Range:bytes=0-71763
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.220 Safari/535.1

Response Headers
Connection:Keep-Alive
Date:Tue, 06 Sep 2011 05:07:15 GMT
ETag:"1f48c8-11854-43e4ee482ef40"
Keep-Alive:timeout=15, max=100
Server:Apache/2.0.55 (Ubuntu) PHP/5.1.2 mod_ssl/2.0.55 OpenSSL/0.9.8a

一个奇怪的事情是状态的不同,但也许服务器很聪明,或者与缓存有一些有趣的交互。谁知道呢。

任何帮助将不胜感激。

基因

编辑:2011 年 9 月 6 日

当我删除标签时

 <meta http-equiv="content-type" content="text/html; charset=UTF-8">

从我的 HTML 页面的 &lt;head&gt; 元素开始,许多(但不是全部)PDF 开始正确呈现。这显然是标题中另一个元标记的重复:

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>

这是否有助于揭示潜在问题?

【问题讨论】:

    标签: firefox pdf google-chrome iframe


    【解决方案1】:

    不要将 iframe 的 src 属性设置为 PDF,而是将其设置为包含简单 div 的包装 HTML 文件:

    <!DOCTYPE html>
    <html style="height:100%;">
    <head>
    </head>
    <body style="height:100%;">
        <div id="divContents" style="height:100%;"></div>
    </body>
    </html>
    

    在 javascript 中,div 的内容设置为 object 元素。不幸的是,需要稍微不同的版本才能在所有浏览器上可靠运行(在 IE、Firefox 和 Chrome 上测试):

    (我简化了 divContents 元素的检索和浏览器检测)

    var embed = '<object type="application/pdf" width="100%" height="100%"';
    if (msie) {
        embed += '><param name="src" value="' + pdf + '"/>';
    }
    else if (chrome) {
        embed += ' src="' + pdf + '">';
    }
    else {
        embed += ' data="' + pdf + '">';
    }
    embed += '</object>';
    $("#divContents").html(embed);
    

    更新

    我终于找到了 Chrome 失败的真正原因:是 Accept-Ranges:bytes 字段,没有它,当使用 data 属性时,Chrome 将无法工作。

    • 因此,如果您的服务器能够支持Accept-Ranges 字段,则应确保将其返回给客户端。在这种情况下,您可以使用 pdfobject 库在框架或 div 中显示 PDF。
    • 如果没有,您可以使用上面的代码在框架或 div 中显示 PDF。

    【讨论】:

    • 谢谢,当我回到那个项目时,我会看看这个策略。
    【解决方案2】:

    过去曾报告过一些关于在 iframe 中加载 pdf 的问题,包括 Firefox 和 Chrome(尤其是当 Content-Type 和 Content-Disposition 等标头未正确设置时)。

    您可能应该使用&lt;object&gt; 标签在您的页面中嵌入 pdf,而不是 iframe,但更简单的解决方案是 pdfobject 库。为了验证这是否有效,您可以使用 Chrome 和 Firefox 浏览 this jsfiddle

    此外,您可以在您的服务器中使用 代理脚本 流式传输 PDF:您的页面将指向代理脚本并传递一个标识符(这样它就不会被轻易入侵)和该脚本将下载并发送具有正确标题的匹配 pdf 到浏览器。

    最后,关于不同状态码的说明:在第一个响应中,服务器向浏览器发送了Last-ModifiedETag,其中包含文件的时间戳和哈希值;因此浏览器在第二个请求中只请求资源

    If-Modified-Since:Wed, 07 Nov 2007 04:07:49 GMT
    If-None-Match:"1f48c8-11854-43e4ee482ef40" 
    

    由于资源没有改变,第二个响应是304。

    【讨论】:

    • pdfobject 库本质上就是这行代码:targetNode.innerHTML = '&lt;object data="' +url +'" type="application/pdf" width="' +width +'" height="' +height +'"&gt;&lt;/object&gt;';。不幸的是,这在 Chrome 中不起作用(请参阅我的回答)。
    • @mhu 您的示例可能有效,也可能无效,但我认为您对 PDFObject 有点粗心,因为它完美支持 Chrome。尝试使用 Chrome 或 Firefox 访问examples
    • 嗯...如果您使用 PDFObject,则不需要 iframe。你能分享你正在使用的 html(例如通过 pastebin 或 jsfiddle)吗?
    • 我的项目中需要 iframe。请参阅我对 html 的回答。如果在这种情况下使用 data-attribute,则 PDF 不会在 Chrome 中显示,但使用 src-attribute 会。
    • 这是Accept-Ranges:bytes 字段,没有它,当使用data 属性时,Chrome 将无法工作,请参阅我的更新答案。我会奖励你的,因为在不同的服务器上测试你的例子给了我洞察力。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-10
    • 2012-01-06
    • 2015-11-19
    • 2016-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多