跨域,CORS,JSONP

71 阅读1分钟

同源策略

源 = 协议 + 域名 + 端口号

如果两个url的协议、域名、端口号完全一致,那么这两个url就是同源的

举例:baidu.comwww.baidu.com 不同源

完全一致才算同源

同源策略

浏览器规定

  • 如果JS运行在源A里,那么就只能获取源A的数据,不能获取源B的数据,即不允许跨域

同源策略: 不同源的页面之间,不准互相访问数据

解决办法

  • 用CORS:需要提前声明,在响应头里添加参数
response.setHeader('Access-Control-Allow-Origin','http://mx.com:9999')
  • JSONP

    JSONP:我们在跨域的时候,由于当前浏览器不支持CORS或者因为某些条件不支持CORS,我们必须使用另外一种方式来跨域。于是我们就请求一个JS文件,这个JS文件会执行一个回调,回调里面就有我们的数据。回调的名字是什么?回调的名字是可以随机生成的一个随机数,然后我们把这个名字以callback的参数传给后台,后台会把这个函数再次返回给我们并执行。

    JSONP的优点:

    1. 兼容IE;
    2. 可以跨域;

    JOONP的缺点:

    1. 由于它是script标签,所以它读不到AJAX那么精确的状态,它不知道状态码是什么,也不知道整个响应头是什么,它只知道成功和失败,因为我们监听onload和onerror
    2. 由于它是script标签,所以它只能发GET请求,JSONP不支持POST

    封装JSONP

function jsonp(url) {
    return new Promise((resolve,reject) => {
        const random = "hmxJSONPCallbackName" + Math.random();
        window[random] = data => {
            resolve(data);
        };
        const script = document.createElement("script");
        script.src = `${url}?callback=${random}`;
        script.onload = () => {
            script.remove();
        };
        script.onerror = () => {
            reject();
        };
        document.body.appendChild(script);
    });
}
jsonp('http://qq.com:8888/friends.js')
    .then((data)=>{
        console.log(data)
    })

参考资料:饥人谷