几种跨域处理

jsonp跨域

由于 web 页面上调用 js 文件不受浏览器同源策略的影响,所以通过动态创建script标签的方式进行跨域请求,
主要原理就是在script的src上,接口url+callback回调函数名称+其他参数。callback是服务端约定好的回调函数,你也可以叫其他名字。
当服务端接收到这个请求时,就会在你传入的callback回调函数中传入返回值,并返回‘’执行该回调函数‘’

// jsonp/server.js
const url = require('url');
	
require('http').createServer((req, res) => {
	const data = {
		x: 10
	};
	// 拿到回调函数名
	const callback = url.parse(req.url, true).query.callback;
	console.log(callback);
	res.writeHead(200);
	res.end(`${callback}(${JSON.stringify(data)})`);

}).listen(3000, '127.0.0.1');

console.log('启动服务,监听 127.0.0.1:3000');


//前端js
function jsonP(url,callback,params){
   var el = document.createElement('script');
  el.src=url+'?callback='+callback;
  for(let param in params) {
    el.src+=('&'+param+'='+params[param]);
  }
  console.log(el.src)
  document.body.appendChild(el)
}
function callBack(data){
  console.log(data)
}
jsonP("https://c.y.qq.com/rsc/fcgi-bin/fcg_ugc_radio_pro.fcg",'callBack',{
  g_tk: 5381,
  loginUin: 0,
hostUin: 0,
format: 'jsonp',
inCharset: 'utf8',
outCharset: 'utf-8',
notice: 0,
platform: 'yqq',
needNewCode: 0,
cmd: 9,
hostuin: 0,
cid: 205362273
})

通过postMessage进行跨域通信

不同域之间通信
//假设www.baidu.com与zhidao.baidu.com之间互相通信

//www.baidu.com需要做的事情
const domain = 'zhidao.baidu.com';
const eventUp = window.open('zhidao.baidu.com');
eventUp.postMessage("这是我的数据",domain);
window.addEventListener((e) => {
	if (e.source==='zhidao.baidu.com'){
		console.log(e.data)
	}
})



//被打开的zhidao.baidu.com页面需要做的事情
window.addEventListener((e) => {
	if (e.source==='www.baidu.com') {
		console.log(e.data);
		e.postMessage('我收到数据了',e.source)
	}
},false)

postMessage通信的原理的双方相互挟持,也就是如上方www.baidu.com如果要向zhidao.baidu.com发送那他需要拿到对方的window对象并调用window的postMessage进行发送。
同理,相同域内,不同iframe之间也是这个方式通信,只是a向b通信时,a之选哟调用document.getElementsByTagName('iframe')难道对象的iframe窗口即可

利用url上hash改变来通信

通常用于iframe框架之间通信

//假设两个页面a.html和b.html
//a向b发送信息
    function checkHash() {
      try {
                let data = location.hash ? location.hash.substring(1) : '';
                console.log('获得到的数据是:', data);
        }catch(e) {
      }
    }
    window.addEventListener('hashchange', checkHash );

 var iframe = document.getElementById('iframeB');
    iframe.src='http://localhost:8080/b.html#data';
//b接收到a发来的信息,进行响应
  function checkHash() {
      try {
                let data = location.hash ? location.hash.substring(1) : '';
                console.log('获得到的数据是:', data);
                callback();//接收到数据后进行响应
        }catch(e) {
      }
    }
    window.addEventListener('hashchange', checkHash );
  function callback() {
        const data = "somenumber: 1111";
        try {
          parent.location.hash = data;
        }catch(e) {
          // ie, chrome下的安全机制无法修改parent.location.hash
          // 所以要利用一个中间的代理iframe 
          var ifrproxy = document.createElement('iframe');
            ifrproxy.style.display = 'none';
            ifrproxy.src = 'http://localhost:8080/c.html#' + data;     //该文件在请求域名的域下
            document.body.appendChild(ifrproxy);
        }
  }

最后一种是cors跨域处理

这种方式一般时候服务端设置headers的Acess-Control-Allow-Origin为对应支持的域名即可

posted @ 2018-08-10 15:26  happyYawen  阅读(211)  评论(0编辑  收藏  举报