同源策略
含义
起初的含义是指,A网页设置的Cookie,B网页不能打开,除非这两个网页”同源”。所谓”同源”是指一下几个相同:
- 协议相同(http,https,http2等)
- 域名相同(www.example.com)
- 端口相同(www.example.com:3000)
目的
同源策略的出现时为了保护用户信息的安全。如果用户登录了A网站,又去浏览其他网站。如果其他网站可以获取到A网站的Cookie,重要用户信息可能就会泄露。
通过XHR实现Ajax的一个主要限制,来自于跨域安全策略。这种安全策略可以防止某些恶意行为,但合理的实现跨域请求对某些应用来说也是非常必要的。
限制范围
目前,如果非同源,共有三种行为受到限制:
- Cookie、LocalStorage 和 IndexedDB 无法获取
- DOM 无法获得
- AJAX 请求不能发送
规避方法
我们首先构建出一个跨域的环境方便测试:
|
|
- 通过
express
分别在3000和4000端口启动两个服务 - 默认server为3000端口、client在4000端口
|
|
|
|
|
|
环境搭建成功后,在4000端口上的js通过Ajax向3000端口的服务发送请求,就会触发跨域安全策略。
下面就介绍几种CORS(Cross-Origin Resource Sharing)的方法:
原生支持
Firefox 3.5+、Safari 4+、Chrome等主流浏览器都通过XMLHttpRequest对象实现了CORS的原生支持。
|
|
同时需要对接口进行设置。通过设置Access-Control-Allow-Origin
头可以决定来自哪些域的请求可以被实现。
|
|
设置成功后重启服务,我们可以看到这时的跨域请求已经发送成功,在client的index.html页面中已经可以看到请求得到的内容
图像Ping
|
|
通过创建一个img
标签,并且设置对应的src
,可以向目标url发送请求,但是这种方法无法收到返回的数据,只能发送GET
请求。由于无法得到返回的数据,我们稍微改一下接口的代码
|
|
这样我们通过命令行的输出就能够判断http://localhost:3000
是否收到了请求。
刷新index.html页面后,我们可以看到控制台输出了fail
,即图片加载失败,但是命令行会输出receive get request
,即已经收到了通过图像Ping发送的GET
请求。
JSONP
顾名思义 JSONP = JSON + Padding
不理解没关系,看下面的例子就知道了
|
|
|
|
不难看出,服务端接口此时返回一个字符串,这个字符串的格式为callback({test: 1})
,即用一个函数包含了一个JSON,这就是JSONP名字的由来。客户端收到这个字符串后,会对其进行调用。注意这里的callback
就是作为请求的参数传给接口的值,因此这个参数要和自己定义的回调函数同名。
刷新页面重新请求时,控制台打印出1
。这是因为返回的handleResponse({test: 1})
字符串执行后,相当于把JSON格式的数据作为参数,这样在函数内部就能获取到了。
如果实在不理解的话,可以直接访问这个链接,它会返回一个JSONP字符串。
部分选自这篇博客
转载请注明出处