Internet Explorer 跨域:不发送预检
Internet Explorer Cross Domain: Not sending preflight
我发现了几个类似的线程。但是,none 似乎还没有奏效。
问题
在我们当前的生态系统中,我们的 http-apis 拥有三台服务器。两个用于测试,一个用于生产。
最近我们发布了 client-side 使用 AngularJS 的网络应用程序。由于客户端应用程序是为我们的客户提供的,因此与我们 api 的通信是跨域的。 Web 应用程序在 Chrome、Safari 和 Firefox 以及所有 api 中正常运行。但是,对于第三个 api,Internet Explorer(11) 拒绝发送预检(选项)请求,这使客户端无法与 api 进行通信。在另外两个 api 中,Web 应用程序在 IE 中运行良好。
api 如下:
https://api.doma.in/accesstoken -- Works in IE11
https://api2.doma.in/accesstoken -- Works in IE11
https://api3.doma.in/accesstoken -- Does not send preflight in IE11.
需要注意的是,三台服务器或多或少是克隆的,所以设置不会有太大差异。
但是,我收到的错误消息中的错误如下:
SEC7118: XMLHttpRequest https://api3.doma.in/accesstoken required CORS (Cross Origin Resource Sharing).
SEC7119: XMLHttpRequest https://api3.doma.in/accesstoken required CORS Preflight.
SCRIPT7002: XMLHttpRequest Network error 0x80070005, Access Denied.
在网络日志中它只显示预检请求被取消,因此没有请求或响应headers。
我能够使用 openssl 识别问题。通过 运行 $ openssl s_client -connect <url/domain>:443 -state
我发现了一个 ssl 错误。
Api 1 和 2 在 openssl 的结果中显示如下:
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server key exchange A
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL_connect:SSLv3 read finished A
在 api 3(失败的 api-服务器)上,结果显示了两个额外的操作:
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server key exchange A
SSL_connect:SSLv3 read server certificate request A //This
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client certificate A //This
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL_connect:SSLv3 read finished A
我还没有在服务器上解决这个问题。与此同时,我正在使用 xdomain "hack"(https://github.com/jpillora/xdomain)。它真的很容易设置并且工作正常。
添加有关根本原因的更多详细信息,并节省其他人调查这么多小时/几天的时间。
在我的实例中,IE 11 遵循正确的规范,并且在发出 CORS 预检请求时没有发送客户端证书。
规范的这一部分在 Chrome 和其他浏览器中被忽略,它们确实发送客户端证书。
在我的例子中,我们使用的是 Pivotal Cloud Foundry,必须更改配置以确保连接不会被拒绝。
要轻松验证这是否是您的问题,请下载并安装 fiddler,将其配置为支持 HTTPs 并再次测试损坏的 CORS,
我的与 Fiddler 一起工作,但在直接连接到远程服务器时没有。
我发现了几个类似的线程。但是,none 似乎还没有奏效。
问题
在我们当前的生态系统中,我们的 http-apis 拥有三台服务器。两个用于测试,一个用于生产。
最近我们发布了 client-side 使用 AngularJS 的网络应用程序。由于客户端应用程序是为我们的客户提供的,因此与我们 api 的通信是跨域的。 Web 应用程序在 Chrome、Safari 和 Firefox 以及所有 api 中正常运行。但是,对于第三个 api,Internet Explorer(11) 拒绝发送预检(选项)请求,这使客户端无法与 api 进行通信。在另外两个 api 中,Web 应用程序在 IE 中运行良好。
api 如下:
https://api.doma.in/accesstoken -- Works in IE11
https://api2.doma.in/accesstoken -- Works in IE11
https://api3.doma.in/accesstoken -- Does not send preflight in IE11.
需要注意的是,三台服务器或多或少是克隆的,所以设置不会有太大差异。
但是,我收到的错误消息中的错误如下:
SEC7118: XMLHttpRequest https://api3.doma.in/accesstoken required CORS (Cross Origin Resource Sharing).
SEC7119: XMLHttpRequest https://api3.doma.in/accesstoken required CORS Preflight.
SCRIPT7002: XMLHttpRequest Network error 0x80070005, Access Denied.
在网络日志中它只显示预检请求被取消,因此没有请求或响应headers。
我能够使用 openssl 识别问题。通过 运行 $ openssl s_client -connect <url/domain>:443 -state
我发现了一个 ssl 错误。
Api 1 和 2 在 openssl 的结果中显示如下:
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server key exchange A
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL_connect:SSLv3 read finished A
在 api 3(失败的 api-服务器)上,结果显示了两个额外的操作:
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server key exchange A
SSL_connect:SSLv3 read server certificate request A //This
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client certificate A //This
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL_connect:SSLv3 read finished A
我还没有在服务器上解决这个问题。与此同时,我正在使用 xdomain "hack"(https://github.com/jpillora/xdomain)。它真的很容易设置并且工作正常。
添加有关根本原因的更多详细信息,并节省其他人调查这么多小时/几天的时间。
在我的实例中,IE 11 遵循正确的规范,并且在发出 CORS 预检请求时没有发送客户端证书。
规范的这一部分在 Chrome 和其他浏览器中被忽略,它们确实发送客户端证书。
在我的例子中,我们使用的是 Pivotal Cloud Foundry,必须更改配置以确保连接不会被拒绝。
要轻松验证这是否是您的问题,请下载并安装 fiddler,将其配置为支持 HTTPs 并再次测试损坏的 CORS, 我的与 Fiddler 一起工作,但在直接连接到远程服务器时没有。