之前把Ajax弄懂了,现在回头再看跨域终于有了清晰的理解。 本文包括以下内容

  • 什么是同源
  • 什么是跨域
  • CORS实现跨域
  • JSONP实现跨域

什么是同源

如果两个url它们的协议,域名和端口(如果有指定,不指定默认都是80端口)都相同,则这两个页面有相同的源。 如https://www.example.com/dir/index.html,它的协议是https://,域名是www.example.cm,端口是80(80是默认端口,可以省略)

什么是跨域

跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,由于同源策略,会限制以下行为

  1. cookie,localStorage,indexDB无法读取
  2. JS和DOM对象无法获得
  3. AJAX请求不能发送

CORS

CORS是实现跨域的一种方式,它的全称是Cross-Origin Resource Sharing 比如我想让http://carri.com:9999请求http://gao.com:8888的资源 可以在http://gao.com:8888响应头添加 response.setHeader('Access-Control-Allow-Origin', 'http://carri.com:9999')

JSONP跨域

JSONP是实现跨域的一种方式,当浏览器无法使用CORS时,我们可以使用JSONP。它的原理是,虽然我们无法访问另外一个网站的数据,但是可以用script标签引用这个网站的JS,服务器收到请求后,会将数据放在一个回调函数里(回调函数的名字是一个随机生成的随机数)传回来。优点是可以跨域并且兼容IE,但由于它是script标签,所以它读不到响应的状态,且只能发GET请求,不支持POST

下例是一个封装的JSONP,用于在其他网站访问我模拟的域名里的qq文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
function jsonp(url) {
    return new Promise((resolve, reject) => {
        const random = "frankJSONPCallbackName" + Math.random();
        window[random] = data => {
            resolve(data);
        };// 一个回调函数
        const script = document.createElement("script");
        script.src = `${url}?callback=${random}`// 服务器会根据这个查询参数得到random
        script.onload = () => {
            script.remove();
        };// 成功之后删掉这个script标签,防止页面冗杂
        script.onerror = () => {
            reject();
        }
        document.body.appendChild(script);
    });
}
jsonp('http://localhost:8888/qqf.js').then((data) => {
    console.log(data);

})// 加载成功后,后台打出data