同源是指:协议、域名、端口 三者相同,三者相同,则称为在同一个域中。
一个域内的脚本仅仅具有本域内的权限,可以理解为本域脚本只能读写本域内的资源,而无法访问其它域的资源。现代浏览器在安全性和可用性之间选择了一个平衡点。在遵循同源策略的基础上,选择性地为同源策略“开放了后门”,如script、img、link等允许跨域访问资源,允许这些资源可以部署在其他服务器上,从而降低服务器的压力。
同源限制最常用的体现在:
Cookie:浏览器发起的请求只能带本域下的cookie;如果没有这个限制,cookie相当于暴露在所有网站下,所有人都可以读取。
DOM:不允许通过iframe来加载其他域下的页面;因为父页面可以获取到iframe中的dom,从而获取到里面用户信息,不安全。
Ajax:不允许通过ajax来跨域请求资源
localStorage:不允许跨域访问别人localStorage
CORS
启用CORS支持可以使AJAX跨域请求,不过需要另一个域的后端做一些相应配合才可以。接下来演示一下AJAX跨域错误以及如何启用CORS(goLang后端):
一个简单的服务器,监听了19090端口,对请求回应一个简单的字符串:
以下客户端代码去请求上面的接口。页面运行在webstorm server 63342端口中,两者端口不同,属于跨域。
运行报错:
但是响应中的确有我们想要的数据:
可见,服务器已经针对我们的请求作出了响应,只不过被浏览器给拦截了。解决办法就是在服务器中添加一个响应头,把服务器中这句代码打开:
以上相当于配置一个白名单,允许这个域下进行跨域请求,让浏览器不要去拦截我的响应。重新运行,可以成功请求了。
跨域请求下的cookie操作
在服务器响应的同时,回写一个cookie以及输出请求中的cookie
运行之前的客户端代码,可见完成跨域请求后,浏览器的确收到了一个cookie
客户端再执行相同的请求,发现服务器接受到的请求中,没有带上次的cookie。在客户端请求时多加一句代码:
再次请求,发现请求中已经有带cookie了,而且服务器可以接收到cookie了:
服务器响应后,浏览器再次报错,看来响应又被拦截了
需要在服务器多加一行代码:
重启服务器,一切都正常运行了,跨域请求可以带上cookie了,而且当前脚本可以获取那个域下的cookie了: