跨域

什么是跨域

假设一种情景

我对某网站要搞点小心思,因为对方服务器进不了,所以我把小心思放在我的服务器,封装成一个接口暴露出去,然后等我使用他的网站时,再请求我服务器的接口,搞烂他!ttk !

我真聪明!

。。。。。。

origin cors?好吧这个方法好像行不通,那我换个方法,吧小心思包装成一个软件,在互联网传播,等他服务器下载之后运行,我再植入到他的网站首页的script标签运行,偷偷冲他的网站!!嘿嘿嘿我真聪明!

W8JCre

<!-- index.html --><body>  ooooshino的网站</body><script>  // 我们通过某种手段想让对方网站运行我们的端口的脚本  fetch("http://localhost:8081").then(res=>{    console.log("在这里做小动作");  })</scrip>

5t0d92

????

傻逼浏览器,阻止我积累战绩!ttk!!!

以上这些都是跨域导致的错误,跨域是浏览器为了请求安全而引入的基于同源策略的安全特性,需注意的是,这个跨域报错是浏览器的行为,和服务端没有关系,请求是正常返回了,只是卡在了浏览器这边

MDN是这样说明的:

  • 如果两个 URL 的 protocolport (en-US) (如果有指定的话)和 host 都相同的话,则这两个 URL 是同源。这个方案也被称为「协议/主机/端口元组」,或者直接是 「元组」。(元组是指一组项目构成的整体,双重/三重/四重/五重/等的通用形式)
    7bsguZ

我们上面的情况有host或者port不同,其他不变的情况,都造成了跨域问题,也叫同源策略

解决方案

目前较为流行的有三种

  1. cors
  2. jsonp
  3. 反向代理

1. CORS通信(Cross-Origin Resource Sharing)

cors是http的一部分,它允许服务端来指定哪些主机可以从这个服务端加载资源。采用cors的话只需要服务端修改一下请求头的Access-Control-Allow-Origin字段,该方案涉及到服务端,前端不需要修改,例如上面的例子我们可以改成:

除了上面这个请求头,添加的时候还有以下选择:

字段功能
Access-Control-Allow-Origin表示允许的来源
Access-Control-Allow-methods表示允许的请求方法
Access-Control-Allow-Headers表示允许的请求头
Access-Control-Allow-Credentials表示允许携带认证信息
app1.get("/", (req, resp) => {
  resp.header("Access-Control-Allow-Origin",'*')
    // 或者直接添加header字段「Access-Control-Allow-*」也可以
  resp.send("嘿嘿嘿,成功访问后我要搞烂你!!!")
});
<body>  ooooshino的网站</body><script>    //前端再去访问该api就不会发生跨域问题了  fetch("http://localhost:8081").then((res) => {    res.text().then((data) => {      alert(data);    });  });</script>

HLbD7h

2. jsonp

JSONP 的原理是利用了浏览器加载 JavaScript 资源文件时不受同源策略的限制而实现的。把我们的请求变成一个资源请求,然后吧」小心思「弄成函数,当作资源请求的参数传入,这样吧函数在服务端处理后又返回去浏览器,就可以了!

<body>  ooooshino的网站</body><script>  let trick = (data) => alert(date);</script><script src="http://localhost:8081?callback=trick"></script>
app1.get("/", (req, resp) => {
  let trickFunction = req.query.callback;
  resp.send(trickFunction+"('嘿嘿嘿,成功访问后我要搞烂你!!!')");
});

RoEGTx

也是成功访问到api了

3. 反向代理

我在这里讲过了,就不多说了

© 2018 ooooshino | 羽森