跨域

发布于 2019-08-21  5 次阅读


什么是跨域

html中,a,img,link,script,iframe等标签都指向一个资源地址。而所谓的跨域请求就是指:当前发起请求的域与该请求指向的资源所在的域不一样。这里的域指的是这样的一个概念:我们认为若协议 + 域名 + 端口号均相同,那么就是同域。

为什么有跨域

同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSRF等攻击。

跨域的场景

  1. cookie localStorage
  2. iframe
  3. ajax

跨域实现

jsonp

    function jsonp({url,params,cb}) {
      return new Promise((resolve,reject)=>{
        let script = document.createElement('script');
        window[cb] = function (data) {
          resolve(data);
          document.body.removeChild(script);
        }
        params = {...params,cb} // wd=b&cb=show
        let arrs = [];
        for(let key in params){
          arrs.push(`${key}=${params[key]}`);
        }
        script.src = `${url}?${arrs.join('&')}`;
        document.body.appendChild(script);
      });
    }
    // 只能发送get请求 不支持post put delete
    // 不安全 xss攻击  不采用
    jsonp({
      url: 'http://localhost:3000/say',
      params:{wd:'我爱你'},
      cb:'show'
    }).then(data=>{
      console.log(data);
    });

cors

// 设置哪个源可以访问我
res.setHeader('Access-Control-Allow-Origin', origin);
// 允许携带哪个头访问我
res.setHeader('Access-Control-Allow-Headers','name');
// 允许哪个方法访问我
res.setHeader('Access-Control-Allow-Methods','PUT');
// 允许携带cookie
res.setHeader('Access-Control-Allow-Credentials', true);
// 预检的存活时间
res.setHeader('Access-Control-Max-Age',6);
// 允许返回的头
res.setHeader('Access-Control-Expose-Headers', 'name');

postMessage

window.name

location.hash

http-proxy

nginx

websocket

//server
let express = require('express');
let app = express();
let WebSocket = require('ws');
let wss = new WebSocket.Server({port:3000});
wss.on('connection',function(ws) {
  ws.on('message', function (data) {
    console.log(data);
    ws.send('我不爱你')
  });
})
//client
let socket = new WebSocket('ws://localhost:3000');
socket.onopen = function () {
    socket.send('我爱你');
}
socket.onmessage = function (e) {
    console.log(e.data);
}

document.domain


这个时间很美好,但它也很残酷