什么是跨域HTTP请求?
JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象。比如HTML中a/form/img/css/script/iframe/ajax都可以指向资源,如果发起请求的资源所在域不同于该请求所指向资源所在的域的HTTP请求就叫做跨域HTTP请求。
何为不同的域?
协议+域名+端口号都相同才是同域,有一个不相同都不行。
为什么要有跨域限制?
想一想,如果不做跨域限制,将产生什么问题:
- iframe嵌入:一个恶意网站的页面通过iframe嵌入了支付宝的登录页面(两者不同域),如果没有任何限制,恶意网页上的javascript脚本就可以在用户登录银行的时候获取用户信息进行恶意操做
- ajax请求:跨域请求别人的AJAX登录接口,也可以获取到用户信息进行恶意操做
如何对跨域进行限制?
- 直接不允许跨域请求
- 服务端可以根据相关的header判断来源,限制访问。但header可以伪造呀~
- 浏览器发起跨域请求时,进行限制,即同源策略
同源策略
1、限制来自不同源的document或脚本,对当前document读取或设置某些属性
2、禁止ajax直接发起跨域HTTP请求(其实可以发送请求,结果被浏览器拦截,不展示)
3、允许img/css/script(拥有src的标签都有跨域的能力。加载下来就属于当前域了)
4、允许跨域的连接、跳转、表单提交(带来了跨站请求伪造CSRF问题)
怎样实现跨域?
AJAX跨域请求实现方式:
- 通过代理:自己的服务器实现接口,后台调用其他域的接口
- JSONP:服务端调用本地js,并将结果带回
- CORS:扩展HTTP协议,根据服务端返回的有关HEADER来决定是否展示结果
这里主要说一下JSONP和CORS跨域。
JSONP
JSON是一种数据交换格式,而JSONP是一种实现ajax跨域的方式。
原理:
JSONP的原理是利用<script>
标签的src
属性加载资源不受同源策略影响,其本质是向服务端请求一段 js 代码,像这样儿:
|
|
优点:
- 兼容性好,基本全部兼容
缺陷:
- 服务端需要指定JS的方法名
- 只支持
GET
- 确定JSONP请求是否失败并不容易,一般根据超时时间来判断
CORS跨域
CORS(Cross-Origin Resource Sharing)跨域资源共享。它是一个规范,可以简单理解为对HTTP协议进行了扩展,增加了一些http header,让服务器能声明那些来源可以通过浏览器访问该服务器上的资源。
原理:
1、当浏览器发现我们的XHR请求不符合同源策略时,会在请求头添加 Origin 字段,代表请求的来源
2、服务端需要处理请求头部的 Origin 字段,根据情况在响应头中添加
Access-Control-Allow-Origin
指定一个允许向该服务器提交请求的URI.对于一个不带有credentials的请求,可以指定为*,表示允许来自所有域的请求Access-Control-Allow-Methods
在响应预检请求的时候使用.指明资源可以被请求的方式有哪些(一个或者多个)Access-Control-Allow-Headers
在响应预检请求的时候使用.用来指明在实际的请求中,可以使用哪些自定义HTTP请求头
等头信息。缺陷:
兼容性问题
更多:cors