JavaScript跨域
一、什么是JS跨域?
在了解跨域之前,先要知道同源策略。
- 同源策略:是浏览器的一种安全策略,所谓同源是指域名、协议、端口完全相同。在同源策略下,只有同源的地址才可以相互通过 AJAX 的方式请求。而跨域就是只要两个地址中协议、域名、端口有任何一个不相同,那它们之间的请求就被称之为跨域请求。
- JS跨域:指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据。
只要协议、域名、端口有任何一个不同,都被当作是不同的域,之间的请求就是跨域操作。
注意:ip相同,域名不同,也属于跨域;对于端口和协议的不同,只能通过后台来解决。
二、JS跨域解决办法
1.JSONP
JSONP是 JSON with Padding(填充式json)的简写。
在浏览器中,<script>、<img>、<iframe>、<link>等标签都可以跨域加载资源,而不受同源资源的限制。它是借助于 script 标签发送跨域请求。
JSONP由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数,而数据就是传入回调函数中的JSON数据。
JSONP的原理:通过script标签引入一个js文件,这个js文件载入成功后执行我们在url参数中指定的函数,并且会把我们需要的json数据作为参数传入。
例如:
有个a.html页面,它里面的代码需要利用ajax获取一个不同域上的json数据,假设这个json数据地址是http://example.com/data.php,那么a.html中的代码就可以这样:
<script type="text/javascript">
function dosomething(jsondata) {
//处理获得的json数据
}
</script>
<script src="http://example.com/data.php?callback=dosomething"></script>
js文件载入成功后会执行我们在ul参数中指定的函数,并把我们需要的json数据作为参数传入。因此jsonp是需要服务器端的页面进行配合。
<?php
$callback = $_GET['callback'];//得到回调函数名
$data = array('a','b','c');//要返回的数据
echo $callback.'('.json_encode($data).')';//输出
?>
2.CORS
CORS是Cross-Origin Resource Sharing的简称
它是一个解决浏览器跨域限制的W3C标准,全称是“跨域资源共享”。
它允许浏览器向跨域服务器发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
具体来说,根据CORS标准定义,服务端需要在浏览器的跨域请求响应中包含指定消息头,浏览器根据响应消息头知道是否可以访问跨域资源。
这种方案无需客户端作出任何变化(客户端不用改代码),只是在被请求的服务端响应的时候添加一个Access-Control-Allow-Origin 的响应头,表示这个资源是否允许指定域请求。
服务器端配置
CORS常用的配置项有以下几种:
- Access-Control-Allow-Origin(必需)允许的域名,只能填 *(通配符)或者单域名。
- * 表示允许任意源访问,不安全
- http://foo.com 允许指定的源访问 - Access-Control-Allow-Methods(必需)这允许跨域请求的http方法(常见有POST、GET、OPTIONS)。
- Access-Control-Allow-Headers(当预请求中包含Access-Control-Request-Headers时必须包含)这是对预请求当中Access-Control-Request-Headers的回复,和上面一样是以逗号分隔的列表,可以返回所有支持的头部。
- Access-Control-Allow-Credentials(可选) 表示是否允许发送Cookie,只有一个可选值:true(必为小写)。如果不包含cookies,请略去该项,而不是填写false。这一项XmlHttpRequest 对象当中的 withCredentials 属性应保持一致,即 withCredentials为true时该项也为true;withCredentials 为false时,省略该项不写。反之则导致请求失败。
- Access-Control-Max-Age(可选) 以秒为单位的缓存时间。在有效时间内,浏览器无须为同一请求再次发起预检请求。
3、JSONP和CORS的区别
- jsonp是jquery提供的跨域方法;cors是w3c提供的一个跨域标准。
- jsonp 支持所有的浏览器;cors,不支持IE10以下的浏览器。
- jsonp只能用于获取资源即 GET请求;cors支持所有类型的http请求,功能完善。