分享人:梁耀
目录
1.背景介绍
2.知识剖析
3.常见问题
4.解决方案
5.编码实战
6.扩展思考
7.参考文献
8.更多讨论
什么是同源政策?
浏览器的同源策略,限制了来自不同源的"document"或脚本,对当前"document"读取或设置某些属性。 从一个域上加载的脚本不允许访问另外一个域的文档属性。 举个例子: 比如一个恶意网站的页面通过iframe嵌入了银行的登录页面(二者不同源),如果没有同源限制,恶意网页上的javascript脚本就可以在用户登录银行的时候获取用户名和密码。
设想这样一种情况:A网站是一家银行,用户登录以后,又去浏览其他网站。如果其他网站可以读取A网站的 Cookie,会发生什么? 很显然,如果 Cookie 包含隐私(比如存款总额),这些信息就会泄漏。更可怕的是,Cookie 往往用来保存用户的登录状态, 如果用户没有退出登录,其他网站就可以冒充用户,为所欲为。因为浏览器同时还规定,提交表单不受同源政策的限制。 由此可见,"同源政策"是必需的,否则 Cookie 可以共享,互联网就毫无安全可言了。
1995年,网景公司将同源策略这一安全策略引入浏览器,规定不同的‘域’之间的数据相互不可访问。
什么算是同源?
URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口相同,则表示他们同源。
举例来说,http://www.example.com/dir/page.html这个网址,协议是http://, 域名是www.example.com,端口是80(默认端口可以省略)。它的同源情况如下:
http://www.example.com/dir2/other.html:同源
http://example.com/dir/other.html:不同源(域名不同)
https://www.example.com/dir/other.html:不同源(协议不同)
http://www.example.com:81/dir/other.html:不同源(端口不同)
请求不同‘源’的数据就算是跨域。
实现跨域的常见方法有以下几种
1.JSONP跨域
2.nginx反向代理
1.JSONP跨域
JSON(JavaScript Object Notation)和JSONP(JSON withPadding)虽然只有一个字母的差别,其实他们根本不是一回事儿:
JSON是一种数据交换格式,而JSONP是一种依靠开发人员的聪明才智创造出的一种非官方跨域数据交互协议。
我们拿谍战片来打个比方,JSON是地下党们用来书写和交换情报的“暗号”,而JSONP则是把用暗号书写的情报传递给自己同志时使用的接头方式。
一个是描述信息的格式,一个是信息传递双方约定的方法。
Ajax直接请求普通文件存在跨域无权限访问的问题,只要是跨域请求,一律不准; 不过,Web页面上调用js文件时则不受是否跨域的影响(不仅如此,我们还发现凡是拥有”src”这个属性的标签都拥有跨域的能力, 比如(/script/、/img、/iframe/); 恰巧我们已经知道有一种叫做JSON的纯字符数据格式可以简洁的描述复杂数据,更妙的是JSON还被js原生支持, 所以在客户端几乎可以随心所欲的处理这种格式的数据;
这样子解决方案就呼之欲出了,web客户端通过与调用脚本一模一样的方式, 来调用跨域服务器上动态生成的js格式文件(一般以JSON为后缀),显而易见,服务器之所以要动态生成JSON文件, 目的就在于把客户端需要的数据装入进去。 客户端在对JSON文件调用成功之后,也就获得了自己所需的数据,剩下的就是按照自己需求进行处理和展现了, 这种获取远程数据的方式看起来非常像AJAX,但其实并不一样。 为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP, 该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
2.nginx反向代理
Nginx是一个HTTP服务器,可以将服务器上的静态文件(如HTML、图片)通过HTTP协议展现给客户端。
反向代理服务器:客户端本来可以直接通过HTTP协议访问某网站应用服务器,网站管理员可以在中间加上一个Nginx,客户端请求Nginx,Nginx请求应用服务器,然后将结果返回给客户端,此时Nginx就是反向代理服务器。
负载均衡:当网站访问量非常大,一台服务器已经不够用了。于是将同一个应用部署在多台服务器上,将大量用户的请求分配给多台机器处理。Nginx可以通过反向代理来实现负载均衡。
JSONP实现跨域
nginx反向代理
#task6-10
server {
listen 1080;//侦听1080端口
server_name localhost;//域名
location / {
root F:\\task\\JS5\\;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
}
location /carrots-admin-ajax/{
proxy_pass http://120.92.4.89:10498/;
}
}
JSONP的优点是: 它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制; 它的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持; 并且在请求完毕后可以通过调用callback的方式回传结果。 JSONP的缺点则是: 它只支持GET请求而不支持POST等其它类型的HTTP请求; 它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
CORS跨域资源分享
WebSocket通信协议
window.name
document.domain跨子域
location.has跨域
postMessage实现页面之间通信
参考一 : 说说JSON和JSONP,也许你会豁然开朗
参考二 : 古尘师姐在知乎关于Nginx的配置回答
参考三 : 阮一峰—浏览器同源政策及其规避方法
参考四: 跨域的那些事
跨域的方法很多,不同的应用场景我们都可以找到一个最合适的解决方案。
比如单向的数据请求,我们应该优先选择JSONP或者window.name,
双向通信优先采取location.hash,
在未与数据提供方达成通信协议的情况下我们也可以用server proxy的方式来抓取数据。
感谢大家观看
感谢 郭健锋 师兄