详解HTTP跨域
什么是跨域
所谓跨域,全称是 跨源资源共享 (CORS) Cross- Origin Resource Sharing ,是一种基于 HTTP Header 的机制,该机制通过允许服务器标示除了它自己以外的其它 origin(域,协议和端口),这样浏览器可以访问加载这些资源。
举个例子
运行在 domain-a.com 的 JavaScript 代码使用 XMLHttpRequest
分别发起两个请求:
请求A: https://domain-a.com/query
请求B: https://domain-b.com/query
由于发请求的页面站点为 domain-a.com,所以请求 A 属于同源请求,domain-a.com 的后台服务器是允许请求。但是请求 B 的站点域是 domain-b.com,如果要发请求到 domain-b.com,就属于跨源访问,出于安全性考虑,浏览器限制脚本内发起的跨源 HTTP 请求。如下图所示:
因此,为了解决上述问题,跨源域资源共享( CORS )机制就应运而生了。该机制允许 Web 应用服务器进行跨源访问控制,从而使跨源数据传输得以安全进行。
CORS 工作机制
跨源资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。
而且对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨源请求。
只有在服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)。
大致流程如上图所示,CORS 请求失败会产生错误,但是为了安全,在 JavaScript 代码层面是无法获知到底具体是哪里出了问题。你只能查看浏览器的控制台以得知具体是哪里出现了错误。
所有资源访问
在新增的这一组 HTTP 首部字段中,最重要的便是 Access-Control-Allow-Origin,其语法如下:
Access-Control-Allow-Origin:
| *
其中,origin 参数的值指定了允许访问该资源的外域 URI。对于不需要携带身份凭证的请求,服务器可以指定该字段的值为通配符,表示允许来自所有域的请求。
指定资源访问
下面的字段值将允许来自 www.domain-a.com 的请求:
Access-Control-Allow-Origin: http://www.domain-a.com
如果服务端指定了具体的域名而非“*”,那么响应首部中的 Vary 字段的值必须包含 Origin。这将告诉客户端:服务器对不同的源站返回不同的内容。
算作“跨域”
当协议、子域名、主域名、端口号中任意一个不相同时,都算作不同域,不同域之间相互请求资源,就算作“跨域”。
因为JavaScript出于安全考虑,有同源策略。
有一点必须要注意:跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了。之所以会跨域,是因为受到了同源策略的限制,同源策略要求源相同才能正常进行通信,即协议、域名、端口号都完全一致。
实际跨域场景
多个接口突然出现 block:mixed-content 错误,于是排查了一下发现:
错误:https页面去发送http请求报错(浏览器阻止https发送http请求)
标签:
相关文章
-
无相关信息