PDF.js 无法使 range/streaming PDF 工作

PDF.js unable to get range/streaming PDF's working

我们有一个应用程序在我们使用 PDF 的地方运行,但是由于客户使用的 PDF 的大小,我们 运行 遇到了缓存问题。决定查看 streaming/using 范围请求以下载 PDF。

这是我看到的:

accept-ranges: bytes
access-control-allow-credentials: true
access-control-allow-headers: Authorization, Content-Type, body, Content-Length, Accept-Ranges, Range
access-control-allow-methods: GET,POST,PUT,DELETE
access-control-allow-origin: http://example.test
access-control-max-age: 1000
cache-control: max-age=31536000
content-length: 185124353
content-type: application/pdf
date: Thu, 05 Dec 2019 14:03:42 GMT
etag: "some-etag-that-works-nicely"

有很多 CORS,因为我 运行 现在在本地,在我考虑将其推送到开发环境之前。我认为我们已经添加了所有必需的 headers 以使 PDF.js 检测到我们支持范围调用,但它似乎无法正常工作。

当我在行 23744 (v2.3.200) 上深入研究 PDFJS-dist/build/pdf.js 文件时,我看到了这个:

if (getResponseHeader('Accept-Ranges') !== 'bytes') {
 return returnValues;
}

这让我想到;也许这个 getResponseHeader() 是 case-sensitive,出于某种原因,我无法让 API 以我们习惯的整洁 mixed-case 响应它的 headers。所以我决定对它进行一些修改并使其 returnValues return allowRangeRequests = true.

这个工作有点不对劲,因为我看到 200 OK 与上面的 headers 相同(在本地工作时在 OPTIONS 之后),应该取消但不是' t,然后是一堆带有 206 PARTIAL 和增量 range: byte=0-65000 等的新调用。headers 看起来像这样:

REQUEST
range: bytes=0-65535
//...and other headers of course, omitted for brevity.
RESPONSE
accept-ranges: bytes
access-control-allow-credentials: true
access-control-allow-headers: Authorization, Content-Type, body, Content-Length, Accept-Ranges, Range
access-control-allow-methods: GET,POST,PUT,DELETE
access-control-max-age: 1000
cache-control: max-age=31536000
content-length: 65536
content-type: application/pdf

依此类推,这也为我提供了视图中的实际工作 PDF(或至少几页);所以这表明它至少部分有效。

现在为什么我需要 "hack" 这个,我缺少什么 headers PDF.js 来检测我们实际上确实支持范围,因为它似乎已正确实施?这也是为什么它不会因为 "range support detection" 的另一部分而在没有 range: bytes=0-65535 的情况下取消初始提取的原因吗?

我们已经让它工作了,看来 PDFjs 内部实现对 headers 非常挑剔。当您将它与 CORS 结合使用时(因此您首先有一个 OPTIONS 调用),它似乎根本没有选择正确的 headers。这可能是一个错误,但我没有花时间调查并确保我们应该报告它。

其次,HTTP2 SPDY 协议将所有 headers 小写,PDFJS 所依赖的内部实现似乎对 Case-Sensitive headers 很挑剔。当我们禁用 HTTP2 SPDY 并在没有 CORS 的情况下重试时,我们让它正常工作。

这是因为当你发出cross-origin请求时,你只能得到7个简单的响应头,其中不包括'Accept-Ranges'。所以也许你应该配置你的服务器的 Access-Control-Expose-Headers.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers