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为对应支持的域名即可