跨域的几种解决方法

1、jsonp

最常见的一种跨域方式,其背后原理就是利用了 script 标签不受同源策略的限制,在页面中动态插入了 script,script 标签的 src 属性就是后端 api 接口的地址,并且以 get 的方式将前端回调处理函数名称告诉后端,后端在响应请求时会将回调返还,并且将数据以参数的形式传递回去。
前端:

// http://127.0.0.1:8888/jsonp.html
var script = document.createElement('script');
script.src = 'http://127.0.0.1:2333/jsonpHandler?callback=_callback';
document.body.appendChild(script);      //插入script标签
// 回调处理函数 _callback
var _callback = function(obj) {
   for(key in obj) {
     console.log('key: ' + key +' value: ' + obj[key]);
    }
}

后端:

// http://127.0.0.1:2333/jsonpHandler
app.get('/jsonpHandler', (req, res) => {
  let callback = req.query.callback;
  let obj = {
    type: 'jsonp',
    name: 'weapon-x'
  };
  res.writeHead(200, {"Content-Type": "text/javascript"});
  res.end(callback + '(' + JSON.stringify(obj) + ')');
})

在 jsonp.html 中打开控制台可以看到返回数据的输出:


image

2、CORS

Cross-Origin Resource Sharing(跨域资源共享)是一种允许当前域(origin)的资源(比如html/js/web service)被其他域(origin)的脚本请求访问的机制。
当使用 XMLHttpRequest 发送请求时,浏览器如果发现违反了同源策略就会自动加上一个请求头 origin,后端在接受到请求后确定响应后会在 Response Headers 中加入一个属性 Access-Control-Allow-Origin,值就是发起请求的源地址(http://127.0.0.1:8888),浏览器得到响应会进行判断 Access-Control-Allow-Origin 的值是否和当前的地址相同,只有匹配成功后才进行响应处理。
前端:

// http://127.0.0.1:8888/cors.html
var xhr = new XMLHttpRequest();
xhr.onload = function(data) {
  var _data = JSON.parse(data.target.responseText)
  for(key in _data) {
    console.log('key: ' + key + ' value: ' + _data[key]);
  }
};
xhr.open('POST','http://127.0.0.1:2333/cors',true);
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.send();

后端:

// http://127.0.0.1:2333/cors
app.post('/cors', (req, res) => {
  if(req.headers.origin) {
    res.writeHead(200, {
      "Content-Type": "text/html; charset=UTF-8",
      "Access-Control-Allow-Origin": 'http://127.0.0.1:8888'
    });
    let people = {
      type: 'cors',
      name: 'weapon-x'
    }
    res.end(JSON.stringify(people));
  }
})

可以在开发者工具里面看到请求的详细信息,并且在控制台也可以看到返回的数据输出:


image

3、postmessage跨域

在 HTML5 中新增了 postMessage 方法,postMessage 可以实现跨文档消息传输 Cross Document Messaging,IE8,Firefox 3,Opera 9,Chrome 3 和 Safari 4 都支持 postMessage。
该方法可以通过绑定 window 的 message 事件来监听发送跨文档消息传输内容。
使用 postMessage 实现跨域的话原理就类似于 jsonp,动态插入 iframe标签,再从 iframe 里面拿回数据
,私认为用作跨页面通信更加适合

你可能感兴趣的:(跨域的几种解决方法)