跨域(Cross-Origin)

同源政策

同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制
同源:协议、主机、端口一致
有三个标签允许跨域加载资源

  1. <img src='xxx'>
  2. <link href='xxx'>
  3. <script src='xxx'>

解决跨域的方法

  1. JSONP
    利用的是script标签没有跨域限制。缺点:仅支持get方法,可能会遭受XSS攻击
function jsonp(url, data = {}, callback = "callback") {
  data.callback = callback;
  let params = [];
  for (let key in data) {
    params.push(key + "=" + data[key]);
  }
  // 创建script元素
  let script = document.createElement("script");
  script.src = url + "?" + params.join("&");
  document.body.appendChild(script);
  // 返回promise
  return new Promise((resolve, reject) => {
    window[callback] = (data) => {
      try {
        resolve(data);
      } catch (e) {
        reject(e);
      } finally {
        // 移除script元素
        document.body.removeChild(script);
      }
    };
  });
}
  1. CORS,跨域资源共享
    后端配置响应头Access-Control-Allow-Origin为*。分为简单请求和复杂请求:
    简单请求:1.请求方法为get、head、post;2.Content-Type为text/plain、multipart/form-data、application/x-www-form-urlencoded
    复杂请求:不符合以上条件的请求。复杂请求在请求前会先发起一个options请求,通过该请求来知道服务端是否允许跨域(白名单)

  2. postMessage
    postMessage()是H5的API,允许来自不同院的脚步采用异步方法进行有限的通信,可以实现跨脚本文档、多窗口、跨域消息传递

  3. node中间件代理
    如果我们用的是node起的前端服务,那我们可以使用node来进行反向代理。利用的是服务器之间没有跨域限制
    代理服务器接收到客户端请求,将请求转发给真正的目标服务器,拿到目标服务器的响应并把响应转发给客户端

const proxy = require('http-proxy-middleware') // 引入代理中间件
app.use(proxy('/a',{target:'http://127.0.0.1:8080'}))
  1. nginx反向代理
    跨域只是浏览器向服务器发送请求的时候,浏览器的限制。而服务器和服务器之间是没有跨域的限制的。反向代理是利用代理服务器接收到请求之后,转发给真正的服务器,并把结果返回到浏览器上。

  2. websocket
    Websocket 是 HTML5 的一个持久化的协议,它实现了浏览器与服务器的全双工通信,同时也是跨域的一种解决方案。

  3. window.name + iframe

  4. location.hash + iframe

  5. document.domain + iframe

总结

CORS 支持所有类型的 HTTP 请求,是跨域 HTTP 请求的根本解决方案
日常工作中,用得比较多的跨域方案是 cors 和 nginx 反向代理
Node 中间件代理还是 nginx 反向代理,主要是通过同源策略对服务器不加限制。

posted @ 2020-07-29 14:01  把我当做一棵树叭  阅读(1119)  评论(0)    收藏  举报