为什么Internet Explorer无法使用NodeJS和Express下载PDF? [英] Why does internet explorer fail to download a PDF using NodeJS and Express?

查看:190
本文介绍了为什么Internet Explorer无法使用NodeJS和Express下载PDF?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



没有错误消息,除了状态栏停止更新并显示:
< img src =https://p.twimg.com/AvSXKvrCQAE_RIi.pngalt =下载(2.97 MB,16.33 MB):>



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

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



编辑 - 包含更多详情:



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



这是提供文件的应用程序路径。静态服务组件确实有效,所以问题似乎在IE检索文件或如何将它们提供给IE的方式中。

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

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

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



在Fiddler,我看到以下内容。



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



如果还有其他我能提供的请求请告诉我。

解决方案

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



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



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



在其他情况下,Adobe会发送一个范围标题这种形式:

 范围:bytes = ab,cd 

其中ab是一个范围而cd是一个范围,它看起来不连续。



我的知识范围标题不是那么广泛,所以我不确定这是否有效。我所做的研究表明没有。



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

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

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



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



解决方案




  • 最简单的解决方案是删除static.js中的Accept-Ranges标题

  • 我实现的更复杂(并且不一定正确)的解决方案是采用 a c 以及 b d 的最大值以创建新范围并在范围检查代码中返回该范围。这个要点展示了我的所作所为: https://gist.github.com/2930131

  • 我认为第三种(可能的)解决方案是监控客户端何时等待数据并对连接执行某些操作(关闭它,发送更多数据 - 我不确定!)。我真的不知道这会怎样,但我会尝试将它推荐给可能的人。



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


I've have a web site I'm building using NodeJS, that needs to serve up some PDFs (among other files).

For reasons I cannot determine, Internet Explorer 8 will fail to completely download the PDF in the Acrobat Viewer first time round (and sometimes multiple times after). Saving the file directly works just fine, but this isn't ideal. Chrome works fine, although I haven't tested other browsers.

There is no error message, other than the status bar stops being updated and shows:

I'm serving the file via NodeJS and the Express (v3, beta2) / Connect framework (it's the Connect Static middleware that is serving the file.) I'm also serving it via SSL, but turning this off doesn't appear to help.

Any ideas would be greatly appreciated! Thanks

EDIT - to include more details:

Firstly - I've upgraded from Express v2 to v3 to attempt to fix the issue - no such luck.

This is the app route that serves the files. The static serving component does work, so the issue appears to be somewhere within how either IE retrieves files or how express serves them to IE.

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

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

As far as errors - I see no 404 error or anything in IE. It simply hangs with a blank screen and the above image showing the amount downloaded in the bottom left status bar. Adobe eventually (~5 minutes later) fails with an alert of: "This file is damaged and cannot be repaired". I know the file is not damaged, because occasionally IE will load it (see Fiddler requests below).

In Fiddler, I see the following.

The first two requests failed, while the third successfully delivered the PDF.

If there is anything else I can provide do let me know.

解决方案

So, I figured out the problem (or at least, a solution or 4).

It took me a while and an extensive amount of research, test cases and all sorts, but I got there eventually.

When IE8 (and possibly other browsers too, but I've not extensively tested) uses the Adobe 9 (not verified with Adobe X or any other version) plugin to request a PDF, occasionally it'll fetch the whole file as one. This is the success that I was seeing and corresponds to request 22 in the Fiddler screenshot above. It seems to grab the whole file if the file is small, but in this case I was testing with a 16MB PDF.

In other cases, Adobe will send a range header of this form:

Range: bytes=a-b, c-d

Where a-b is a range and c-d is a range, which it appears is not continuous.

My knowledge of Range headers isn't that extensive, so I'm not sure if this is valid or not. The research I've done suggests not.

Anyway, in Connect's static.js it uses a range parsing method in lib/util.js called parseRange. This method returns an array of ranges in the following form:

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

In static.js it calls this method and assigns the values to ranges, then it uses ranges[0] to calculate the range, thereby ignoring the values c and d. The range between a and b is the only data read from the file and sent to the request.

I believe Adobe 9 then continues waiting for more data, which causes the hanging I was seeing.

The solutions

  • The simplest solution is to remove the header 'Accept-Ranges' in static.js
  • A more complex (and not necessarily correct) solution I've implemented is to take the minimum of a and c and the maximum of b and d to create a new range and to return that in the range checking code. This gist shows what I've done: https://gist.github.com/2930131
  • A third (possible) solution I believe would be to monitor when the client keeps waiting for data and do something with the connection (close it, send more data - I'm not sure!). I've no idea really how this would work though but I'll try referring it to people who might.

The second solution works for me in my use case. I hope if you've stumbled across it it's useful for you too!

这篇关于为什么Internet Explorer无法使用NodeJS和Express下载PDF?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆