ajax跨域的一些理解和解决方案

1 什么是ajax跨域

ajax 的出现使得网页可以通过在后台与服务器进行少量数据交换,实现网页的局部刷新。但是出于安全的考虑,ajax不允许跨域通信。如果尝试从不同的域请求数据,就会出现错误。如果能控制数据驻留的远程服务器并且每个请求都前往同一域,就可以避免这些安全错误。

2 为什么ajax不允许跨域通信

上文说ajax不允许跨域通信是因为安全的问题。举个例子,你在浏览器中访问银行页面,www.bank.com,这时bank.com的cookie中会保存你的个人信息。然后你又访问一个恶意的网站,这个网站中有一段js代码会去请求www.bank.com。如果允许跨域,代码执行时,会带着bank.com域的cookie去访问www.bank.com,然后www.bank.com通过cookie验证通过,那么你的银行账号就危险了。因此ajax不允许跨域通信

3 一些解决方案

  • 服务端设置Access-Control-Allow-Origin
    这种方式只要服务端把response的header头中设置Access-Control-Allow-Origin为制定可请求当前域名下数据的域名即可。
  • 服务器中转
    让 Web 页面向它源自的 Web 服务器请求数据,并且让 Web 服务器像代理一样将请求转发给真正的第三方服务器。
  • 采用jsonp
    在同源策略下,在某个服务器下的页面是无法获取到该服务器以外的数据的,但img、iframe、script等标签是个例外,这些标签可以通过src属性请求到其他服务器上的数据。利用script标签的开放策略,我们可以实现跨域请求数据,当然,也需要服务端的配合。当我们正常地请求一个JSON数据的时候,服务端返回的是一串JSON类型的数据,而我们使用JSONP模式来请求数据的时候,服务端返回的是一段可执行的JavaScript代码。
    例如,请求http://www.a.com/user?id=123,获取数据:{“id”: 123, “name” : “张三”, “age”: 17}。
    则前端代码:

    1
    <script type="text/javascript" src="http://www.a.com/user?id=123?callback=foo"></script>

    服务端代码:

    1
    2
    3
    4
    5
    $json = json_encode(array("id" => 123, "name" => "张三", "age" => 17));
    if(isset($_GET['callback'])){
    $json = 'try{' . $_GET['callback'] . '(' . $json . ')}catch(e){}';
    }
    echo $json;

    那么就可以使用foo函数处理返回的数据了。
    使用ajax方式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    //方法1
    $.ajax({
    dataType: 'jsonp',
    url: 'http://www.a.com/user?id=123',
    success: function(data){
    //处理data数据
    }
    });

    //方法2
    $.getJSON('http://www.a.com/user?id=123&callback=?', function(data){
    //处理data数据
    });

    //方法3
    function foo(data){
    //处理data数据
    }
    $.getScript('http://www.a.com/user?id=123&callback=foo');