跨域问题的产生和解决方案

什么是跨域

跨域,就是指浏览器不允许页面的脚本执行非同源的页面脚本。它是由浏览器的同源策略引起的,是浏览器对JavaScript施加的安全限制。

什么是同源

同源必须是:协议域名端口均相同,任何一项不同则视为非同源。

例子:
http://www.test.com/index.phphttp://www.test.com/go.php (同源)
http://www.test.com:80/index.phphttp://www.test.com:8080/index.php (非同源,端口不同)
https://www.test.com/index.phphttp://www.test.com/index.php (非同源,协议不同)
http://www.test.com/index.phphttp://www.test2.com/index.php (非同源,域名不同)

解决方案 - JSONP

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,而JSONP(JSON with Pasdding)则是JSON的一种“使用模式”,通过这种模式可以实现数据的跨域获取。

JSONP跨域的原理

在同源策略下,在某个服务器下的页面是无法获取到该服务器以外的数据的,但是imgiframescript等标签是例外的!这些标签可以通过src属性请求到其他非同源服务器上的数据。利用script标签的开放策略,我们就可以实现跨域请求数据,当然,也需要服务端的配合。当我们正常地请求一个JSON数据的时候,服务端返回的是一串JSON类型的数据,而当我们使用JSONP模式来请求数据的时候,服务端返回的就是一段可执行的Javascript代码。

JSONP的实现

理解了原理要实现就不难了。

  1. 在调用数据的时候添加一个回调的函数名作为参数:

    1
    2
    3
    4



    http://www.test.com/order?id=111&callback=del
  2. 如果是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换成*

如果对数据安全性有强要求的话,第二种解决方案无疑更适合。

,小小蔡芽