什么是跨域
跨域,就是指浏览器不允许页面的脚本执行非同源的页面脚本。它是由浏览器的同源策略引起的,是浏览器对JavaScript施加的安全限制。
什么是同源
同源必须是:协议,域名和端口均相同,任何一项不同则视为非同源。
例子:
http://www.test.com/index.php 和 http://www.test.com/go.php (同源)
http://www.test.com:80/index.php 和 http://www.test.com:8080/index.php (非同源,端口不同)
https://www.test.com/index.php 和 http://www.test.com/index.php (非同源,协议不同)
http://www.test.com/index.php 和 http://www.test2.com/index.php (非同源,域名不同)
解决方案 - JSONP
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,而JSONP(JSON with Pasdding)则是JSON的一种“使用模式”,通过这种模式可以实现数据的跨域获取。
JSONP跨域的原理
在同源策略下,在某个服务器下的页面是无法获取到该服务器以外的数据的,但是img、iframe、script等标签是例外的!这些标签可以通过src属性请求到其他非同源服务器上的数据。利用script标签的开放策略,我们就可以实现跨域请求数据,当然,也需要服务端的配合。当我们正常地请求一个JSON数据的时候,服务端返回的是一串JSON类型的数据,而当我们使用JSONP模式来请求数据的时候,服务端返回的就是一段可执行的Javascript代码。
JSONP的实现
理解了原理要实现就不难了。
在调用数据的时候添加一个回调的函数名作为参数:
1
2
3
4
http://www.test.com/order?id=111&callback=del如果是JSON正常模式返回的会是下面的格式
1
2
3
4
{"id":111,"status":"success","msg":""}
如果是JSONP模式的话就会返回下面的格式1
2
3
4
del({"id":111,"status":"success","msg":""});
相当于把JSON数据以参数的形式传给了回调的函数del,并且调用了页面上的del函数。
更严谨点可以:1
2
3
4
try{del({"id":111,"status":"success","msg":""})}catch(e){}
对于服务端来说,只是在原有结果多输出几个字符罢了,相当简单。
解决方案 - 设置Response header跨域策略
通过设置Response的头也可以解决相应的问题1
2
3
4
5
6
7
8
9
10
11
12
13
14
//指定允许访问的域名,
header('Access-Control-Allow-Origin:http://testbb.com');
//指定允许访问的方法
header('Access-Control-Allow-Methods:POST');
//响应头设置
header('Access-Control-Allow-Headers:x-requested-with,content-type');
注意如果想其他所有域名都能访问的话就可以把第一行里面的http://testbb.com
换成*
。
如果对数据安全性有强要求的话,第二种解决方案无疑更适合。