web网站ajax跨域方法总结与解决方案

时间: 2017-10-30阅读: 398标签: 跨域

web前端的同学如果使用ajax,如果请求后端地址和页面访问的地址“URL的首部”不同就会出现访问被拒绝的情况,这就需要跨域来解决前后端的通讯问题,下面将列举一些在实际项目中应用也是比较多的方法。


服务器反向代理解决跨域

指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。  这里已nginx和node来实现如下:

//文件ngix.conf添加代码

location ~ /api {
       //请求后端的地址
	proxy_pass   http://www.b.com:8080;
}

//node的代理如下

proxyTable: {
      '/api': {
        target: 'http://www.b.com:8080/',
        changeOrigin: true,
        //pathRewrite: {'^/api': '/'}是否重写
      }
    },

说明:如果页面url为http://www.a.com的页面需要ajax请求后端http://www.b.com:8080/api/dothis.do的地址。如果设置了反向代理,即可通过http://www.a.com/api/dothis.do来获取数据,就很好的解决了跨域问题的同时并未暴露后端地址给用户。


后端通过Access-Control-Allow-Origin来解决

Access-Control-Allow-Origin是HTML5中定义的一种解决资源跨域的策略。他是通过服务器端返回带有Access-Control-Allow-Origin标识的Response header,用来解决资源的跨域权限问题。

如果应许所有域名的访问,我们可以在header中设置Access-Control-Allow-Origin: * 。

如果应许部分域名访问,这里将已php为例子实现如下,这里将只应许前端URL为http://www.a.com才能访问:

$origin = isset($_SERVER['HTTP_ORIGIN'])? $_SERVER['HTTP_ORIGIN'] : '';
        $allow_origin = array(
            'http://www.a.com',
        );
        if(in_array($origin, $allow_origin)){
            header('Access-Control-Allow-Origin:'.$origin);
        }


jsonp解决get请求的跨域

json是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问。它的局限性主要是支持Get,

这里已php为例返回如下:

<?php
   $data = array();//需要返回的数据
   $callback = $_GET['callback'];
   echo $callback.'('.json_encode($data).')';
   exit;
?>

前端已jquery的ajax请求为例,它封装了jsonp的实现

$.ajax({
    type : "get"//如果
    url : "www.b.com:8080",
    dataType : "jsonp",
    jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名
    success:function(json){},
    error:function(){}
});

这里网上找了一篇原生JS的实现,代码如下:

function ajax(params) {  
 params = params || {};  
 params.data = params.data || {};  
 var json = params.jsonp ? jsonp(params) : json(params);   
 // jsonp请求  
 function jsonp(params) {  
  //创建script标签并加入到页面中  
  var callbackName = params.jsonp;  
  var head = document.getElementsByTagName('head')[0];  
  // 设置传递给后台的回调参数名  
  params.data['callback'] = callbackName;  
  var data = formatParams(params.data);  
  var script = document.createElement('script');  
  head.appendChild(script);  
  //创建jsonp回调函数  
  window[callbackName] = function(json) {  
  head.removeChild(script);  
  clearTimeout(script.timer);  
  window[callbackName] = null;  
  params.success && params.success(json);  
  };  
  //发送请求  
  script.src = params.url + '?' + data;  
  //为了得知此次请求是否成功,设置超时处理  
  if(params.time) {  
   script.timer = setTimeout(function() {  
    window[callbackName] = null;  
    head.removeChild(script);  
    params.error && params.error({  
     message: '超时' 
    });  
   }, time);  
  }  
 };  
 //格式化参数  
 function formatParams(data) {  
  var arr = [];  
  for(var name in data) {  
   arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));  
  };  
  // 添加一个随机数,防止缓存  
  arr.push('v=' + random()); 
  return arr.join('&');  
 }  
 // 获取随机数  
 function random() {  
  return Math.floor(Math.random() * 10000 + 500);  
 }
}