解决跨域的方法——CORS与JSONP

131 阅读2分钟

1. CORS

CORS的缺点

  1. IE10以下不支持

CORS实现跨域

设置响应头 Access-Control-Allow-Origin

/* server.js */
else if (path === "/friends.json") {
  response.statusCode = 200;
  response.setHeader("Content-Type", "text/json;charset=utf-8");
  // CORS 跨域
  response.setHeader("Access-Control-Allow-Origin", "http://localhost:9999")
  response.write(fs.readFileSync("./public/friends.json"));
  response.end();
}
/* CORS方法跨域,使用ajax访问friends.json */
const request = new XMLHttpRequest()
request.open('GET', 'http://localhost:8888/friends.json')
request.onreadystatechange = () => {
  if (request.readyState === 4 && request.status === 200) {
    console.log(request.response);
  }
}
request.send()

2. JSONP

JSONP 实现跨域

JSONP就是创建一个 <script>标签请求js,js把数据夹带过来。

/* server.js */
else if (path === "/friends.js") {
  response.statusCode = 200;
  response.setHeader("Content-Type", "text/javascript;charset=utf-8");
  // const string = fs.readFileSync("./public/friends.js").toString()
  const string = `window["{{xxx}}"]( {{data}} )`
  const data = fs.readFileSync("./public/friends.json").toString()
  const string2 = string.replace("{{data}}",data).replace("{{xxx}}", query.callback)
  response.write(string2);
  response.end();
}
/* JSONP方法跨域 */
const random = Math.random()
console.log(random);
window[random] = (data) => {
  console.log(data);  // 得到数据
}
const script = document.createElement("script")
script.src =`http://localhost:8888/friends.js?callback=${random}`
document.body.appendChild(script)

JSONP 优缺点

  1. 优点:
    • 兼容IE
    • 可以跨域
  2. 缺点:
  • 没办法进行错误处理:由于是<script>标签,所以它读不到ajax那样精确的状态。状态码、响应头都不知道,只知道成功和失败。
  • 不支持post:由于是<script>标签,只能发get请求。

问题:

  1. JSONP是什么? 跨域时由于当前浏览器不支持CORS,所以必须使用另外一种方式实现跨域。于是我们就请求一个js文件,这个js文件会执行一个回调,回调里有我们的数据。
    你这个回调的名字是什么?
    回调的名字可以是一个随机生成的随机数,我们把这个名字以callback的参数传给后台,后台会把这个函数再次返回给我们并执行。

  2. 为什么可以跨域使用CSS、JS、图片?
    同源策略限制的是数据访问,我们引用CSS、JS、图片的时候,其实并不知道其内容,我们只是在引用。能引用但不能读取。

另外:还可以对上述CORS与JSONP方法的代码进行Promise封装,github代码参考链接