为什么Internet Explorer无法使用NodeJS和Express下载PDF?

时间:2012-06-13 17:39:28

标签: internet-explorer node.js pdf ssl

我有一个使用NodeJS构建的网站,需要提供一些PDF(以及其他文件)。

由于我无法确定的原因,Internet Explorer 8将无法在Acrobat Viewer中首次完全下载PDF(有时会多次完全下载)。直接保存文件可以正常工作,但这并不理想。 Chrome工作正常,但我还没有测试过其他浏览器。

除状态栏停止更新外,没有错误消息显示: Downloaded (2.97 MB of 16.33 MB):

我通过NodeJS和Express(v3,beta2)/ Connect框架(它是为该文件提供服务的Connect Static中间件)提供文件。我也通过它提供服务SSL,但关闭它似乎没有帮助。

任何想法都将不胜感激! 感谢

编辑 - 包含更多详细信息:

首先 - 我已经从Express v2升级到v3以尝试解决问题 - 没有这样的运气。

这是提供文件的应用程序路径。静态服务组件确实有效,因此问题似乎出现在IE检索文件或如何将表达式提供给IE的范围内。

app.get('/store/*', ensureAuthenticated, express.static(__dirname + '/../uploads'));

function ensureAuthenticated(req, res, next) {
    if (req.isAuthenticated()) {    
        return next();
    }
} else {
    res.redirect('/login');
}

就错误而言 - 我在IE中看不到404错误或任何错误。它只是挂起一个空白屏幕,上面的图像显示了左下方状态栏中下载的数量。 Adobe最终(约5分钟后)失败并发出警告:"此文件已损坏且无法修复"。我知道文件没有损坏,因为偶尔IE 加载它(参见下面的Fiddler请求)。

在Fiddler,我看到以下内容。 Multiple requests from IE for the PDF. 2 fail, 1 succeeds

前两个请求失败,而第三个请求成功发送PDF。

如果我还能提供其他任何内容,请告诉我。

1 个答案:

答案 0 :(得分:5)

所以,我找出了问题(或者至少是解决方案或4)。

我花了一段时间和大量的研究,测试案例和各种各样,但我最终到了那里。

当IE8(可能还有其他浏览器,但我没有经过广泛测试)使用Adobe 9(未通过Adobe X或任何其他版本验证)插件来请求PDF时,它偶尔会将整个文件作为一。这是我看到的成功,并且对应于上面Fiddler截图中的请求22。如果文件很小,它似乎抓住整个文件,但在这种情况下,我正在使用16MB PDF进行测试。

在其他情况下,Adobe将发送此表单的范围标题:

Range: bytes=a-b, c-d

其中a-b是范围,c-d是范围,它看起来不连续。

我对Range标题的了解并不广泛,所以我不确定这是否有效。我所做的研究表明没有。

无论如何,在Connect的static.js中,它使用lib / util.js中的一个名为parseRange的范围解析方法。此方法以下列形式返回范围数组:

[
   { start: a, end: b },
   { start: c, end: d}
]

在static.js中,它调用此方法并将值分配给范围,然后使用范围[0] 计算范围,从而忽略值 c d a b 之间的范围是从文件读取并发送到请求的唯一数据。

我相信Adobe 9会继续等待更多数据,这会导致我看到的悬挂。

解决方案

  • 最简单的解决方案是删除static.js
  • 中的标题'Accept-Ranges'
  • 我实施的一个更复杂(并且不一定正确)的解决方案是采用 a c 的最小值和 b的最大值 d 创建一个新范围并在范围检查代码中返回该范围。这个要点展示了我所做的:https://gist.github.com/2930131
  • 我认为第三种(可能的)解决方案是监控客户端何时等待数据并对连接执行某些操作(关闭它,发送更多数据 - 我不确定!)。我真的不知道这会如何起作用,但我会尝试将它推荐给可能的人。

第二个解决方案在我的用例中适用于我。我希望如果你偶然发现它对你也很有用!