共计 3988 个字符,预计需要花费 10 分钟才能阅读完成。
问题概要
我从域 A 将 PDF.js 加载到 iframe 中,并以文件作为参数(服务器的完整路径,这将返回 pdf 文档)。PDF.js 将向域 B 的服务器创建一个请求,扩展名为 origin: domain A. 域 B 的服务器返回带有 header 的 pdf 文档 Access-Control-Allow-Origin: domain A,到目前为止一切顺利。
在我的网络选项卡中,我看到对服务器的请求,该请求返回 200 状态 OK,但 PDF.js 抛出错误 Unexpected server response (0) while retrieving PDF
问题是,这里发生了什么,CORS 似乎没问题,但我无法从 PDF.js 获得更多信息,真正的原因是 PDF 无法加载。有没有人遇到过同样的情况?
问题解决
跨域 Ajax 与跨源资源共享
几年前,Web 开发人员正在用头撞 Ajax 的第一堵墙:同源策略。虽然我们惊叹于跨浏览器支持所带来的巨大进步 XMLHttpRequest 对象,我们很快就抱怨没有办法从 JavaScript 向不同的域发出请求。每个人都在自己的网站上设置代理,这是一系列新的开放重定向问题的开始,作为绕过限制的一种方法。尽管开发人员正在使用服务器端代理以及其他技术来解决此限制,但社区对允许本机跨域 Ajax 请求的强烈抗议。许多人没有意识到,几乎所有浏览器(Internet Explorer 8+、Firefox 3.5+、Safari 4+ 和 Chrome)目前都通过称为跨源资源共享的协议支持跨域 Ajax。
跨域资源共享 (CORS)
跨源资源共享 (CORS) 是 W3C 工作草案,定义了跨源访问源时浏览器和服务器必须如何通信。CORS 背后的基本思想是使用自定义 HTTP 标头,让浏览器和服务器充分了解彼此,以确定请求或响应应该成功还是失败。
对于一个简单的请求,即使用 GET 或 POST 且不带自定义标头且正文为 的请求 text/plain,该请求会使用名为 的额外标头发送 Origin。标 Origin 头包含请求页面的来源(协议、域名和端口),以便服务器可以轻松确定是否应该提供响应。示例 Origin 标头可能如下所示:
Origin: https://humanwhocodes.com
如果服务器决定允许该请求,它会发送一个 Access-Control-Allow-Origin 标头,回显与发送的相同来源或“*”(如果它是公共资源)。例如:
Access-Control-Allow-Origin: https://humanwhocodes.com
如果此标头丢失,或者来源不匹配,则浏览器将不允许该请求。如果一切顺利,浏览器就会处理该请求。请注意,请求和响应都不包含 cookie 信息。
前面提到的所有浏览器都支持这些简单的请求。Firefox 3.5+、Safari 4+ 和 Chrome 都支持通过该 XMLHttpRequest 对象使用。当尝试打开不同来源的资源时,此行为会自动触发,无需任何额外代码。例如:
var xhr = new XMLHttpRequest();
xhr.open("get", "https://humanwhocodes.com/some_resource/", true);
xhr.onload = function(){//instead of onreadystatechange
//do something
};
xhr.send(null);
要在 Internet Explorer 8 中执行相同的操作,您需要以相同的方式使用该 XDomainRequest 对象:
var xdr = new XDomainRequest();
xdr.open("get", "
xdr.onload = function(){//do something};
xdr.send();
Mozilla 团队在有关 CORS 的帖子中建议您应该检查该 withCredentials 属性是否存在,以确定浏览器是否通过 XHR 支持 CORS。然后,您可以结合该 XDomainRequest 对象的存在来覆盖所有浏览器:
function createCORSRequest(method, url){var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr){xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined"){xhr = new XDomainRequest();
xhr.open(method, url);
} else {xhr = null;}
return xhr;
}
var request = createCORSRequest("get", "https://humanwhocodes.com/");
if (request){request.onload = function(){//do something with request.responseText};
request.send();}
Firefox、Safari 和 Chrome 中的对象 XMLHttpRequest 与 IE 对象具有足够相似的接口 XDomainRequest,因此该模式工作得相当好。常见的接口属性 / 方法有:
-
abort()– 用于停止已经在进行的请求。
-
onerror– 使用而不是 onreadystatechange 检测错误。
-
onload– 使用而不是 onreadystatechange 检测成功。
-
responseText– 用于获取响应内容。
-
send()– 用于发送请求。
预检请求
CORS 允许通过称为预检请求的透明服务器验证机制使用自定义标头、GET 或 POST 以外的方法以及不同的正文内容类型。当您尝试使用高级选项之一发出请求时,系统会向服务器发出“预检”请求。此请求使用 OPTIONS 方法并发送以下标头:
-
Origin– 与简单请求相同。
-
Access-Control-Request-Method– 请求想要使用的方法。
-
Access-Control-Request-Headers–(可选)正在使用的自定义标头的逗号分隔列表。
假设一个带有名为 的自定义标头的 POST 请求的示例 NCZ:
Origin: https://humanwhocodes.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: NCZ
文章来源地址 https://www.toymoban.com/diary/js/293.html
在此请求期间,服务器可以确定是否允许此类请求。服务器通过在响应中发送以下标头将此信息传达给浏览器:
-
Access-Control-Allow-Origin– 与简单请求相同。
-
Access-Control-Allow-Methods– 允许的方法的逗号分隔列表。
-
Access-Control-Allow-Headers– 服务器允许的标头的逗号分隔列表。
-
Access-Control-Max-Age– 此预检请求应缓存的时间(以秒为单位)。
例子:
Access-Control-Allow-Origin: https://humanwhocodes.com
Access-Control-Allow-Methods: POST, GET
Access-Control-Allow-Headers: NCZ
Access-Control-Max-Age: 1728000
一旦发出预检请求,结果将被缓存响应中指定的时间段;您只会在第一次发出此类请求时产生额外 HTTP 请求的费用。
Firefox 3.5+、Safari 4+ 和 Chrome 均支持预检请求;Internet Explorer 8 没有。
凭证请求
默认情况下,跨源请求不提供凭据(cookie、HTTP 身份验证和客户端 SSL 证书)。您可以通过将该属性设置为 true 来指定请求应发送凭据 withCredentials。如果服务器允许凭据请求,则它会使用以下 HTTP 标头进行响应:
Access-Control-Allow-Credentials: true
如果发送了凭据请求并且此标头未作为响应的一部分发送,则浏览器不会将响应传递给 JavaScript(responseText 是空字符串,status 为 0,并且 onerror() 被调用)。请注意,服务器还可以发送此 HTTP 标头作为预检响应的一部分,以指示允许源发送凭证请求。
Internet Explorer 8 不支持该 withCredentials 属性;Firefox 3.5、Safari 4 和 Chrome 都支持它。
结论
现代 Web 浏览器对跨域 Ajax 提供了大量可靠的支持,但大多数开发人员仍然没有意识到这种强大的功能。使用时只需要一点额外的 JavaScript 工作和一点额外的服务器端工作即可确保发送正确的标头。IE8 的实现在允许高级请求和凭据请求方面落后于其他版本,但希望对 CORS 的支持将继续改进。 文章来源:https://www.toymoban.com/diary/js/293.html
到此这篇关于 PDF.js CORS 问题的文章就介绍到这了, 更多相关内容可以在右上角搜索或继续浏览下面的相关文章,希望大家以后多多支持 TOY 模板网!
原文地址:https://www.toymoban.com/diary/js/293.html
如若转载,请注明出处:如若内容造成侵权 / 违法违规 / 事实不符,请联系站长进行投诉反馈,一经查实,立即删除!