一、同域

1995 年由 Netscape 提出同源策略。

为什么会有同源策略呢,这个问题还要说到 cookie 的设置过程,当我们登录一些购物网站或者是银行系统,服务器会带一个 set-cookie 字段,浏览器会把服务器返回的 cookie 存在本地,下一次请求会带上这个 cookie。这里要是网站里面有恶意链接,请求的时候带上了网站的 cookie,服务器默认该请求是可信任的,可能就会被恶意操作,刷走银行卡里的钱或者盗用账号密码,做其他事情。由此可见,这是一个比较严重的安全问题,所以同源策略就被提出了。

由于浏览器的同源策略,在发送 Ajax 请求时,只接收同域服务器响应的数据资源。满足同域的条件包括三个:

  • 协议相同

  • 域名相同

  • 端口相同

若不满足以上三个条件,则算作跨域。

二、解决跨域问题的方法

1、同域代理

同域代理就是使用 Ajax 向同域下的后台发送请求,同时携带真实请求的地址及参数,后台接受请求后直接根据地址及参数转发请求,因为后台是可以直接模拟 HTTP 客户端发送请求的,所以没有跨域问题,而后台接受到响应数据后再原样返回给前端浏览器,从而实现跨域数据交互。

2、ping img

利用 img 标签可以加载跨域资源的特性,把请求 url 装载到 href 属性里,从而达到请求跨域资源的目的。这种解决方法只能发送 get 请求,而且通信是单项的,无法拿到服务器响应的消息,通常被用于图片点击次数统计,广告浏览次数统计等场景。

3、jsonp

浏览器解析 HTML 代码时,原生具有 src 属性的标签,浏览器都赋予其 HTTP 请求的能力,而且不受跨域限制,所以可以把请求 url 写到 script 的src 属性中去请求跨域资源,在 url 的末尾带上一个回调函数名,服务端根据约定的这个函数名参数做一些处理,返回数据,客户端回调函数取得请求的响应信息,比如下面这个demo

var handler = (resp) => {
console.log(resp)
}
var script = document.createElement('script');
script.src = "http://www.xxx.com?callback=handler";
document.body.appendChild(script);

这种解决跨域问题的方法有以下几个问题:请求错误很难捕获、只能发送 get 请求

4、 跨域资源共享 CORS

CORS 是一个 W3C 标准,全称是”跨域资源共享”(Cross-origin resource sharing)。

实现了 CORS 的浏览器会在发送请求时加上一个 origin 字段,该字段的值是当前页面的源(协议+域名+端口号),服务器收到请求之后,会判断该源是否可信任,若可信任,在响应请求时,会带上一个 Access-control-allow-origin 字段,值可能是当前源或者是 ‘*’。

CORS 默认不支持请求时携带 Cookie 和 http 认证信息,这样做是为了防止 XSS 和 CSRF 攻击。若要带上 Cookie 可以设置 withCredentials 为 true,服务端响应请求设置 Access-Control-Allow-Credentials 为 true,但是这么做 服务端设置 Access-Control-Allow-Origin 为 ‘*’ 将无效。