跨域

2019-07-12  本文已影响0人  椰果粒

写在前面:
跨域是面试经常会问到的问题。
在工作中,开发环境可以用webpack-dev-server,线上环境服务端会配置好。

为什么会出现跨域问题

浏览器同源策略导致了跨域问题

浏览器同源策略

浏览器的同源策略

[协议域名端口] 这三个完全相同,就表示同域。

域名地址的组成

跨域的几种情况,不同域之间进行资源请求就相当于跨域了。

URL 描述 是否允许
http://www.baidu.com/a.js
http://www.baidu.com/a.js
同一域名,协议,端口(80) 允许
http://www.baidu.com/src/a.js
http://www.baidu.com/script/a.js
同一域名,不同文件夹 允许
http://www.baidu.com:8888/a.js
http://www.baidu.com:9999/a.js
不同端口 不允许
http://www.baidu.com/a.js
http://10.42.66.88/a.js
域名和域名对应的IP 不允许
http://www.baidu.com/a.js
http://script.baidu.com/a.js
主域名相同,子域名不同 不允许
http://www.baidu.com/a.js
http://baidu.com/a.js
同一域名,不同二级域名 不允许(cookie也不允许)
http://www.baidu.com/a.js
http://www.google.com/a.js
不同域名 不允许
http://www.baidu.com/a.js
https://www.baidu.com/a.js
不同协议 不允许

为什么浏览器默认不支持跨域(危险性,XSS CSRF攻击)

浏览器是从两个方面做同源策略的,一是针对接口请求,二是针对DOM查询

没有同源策略限制的接口请求(引用)
cookie一般用来处理登录等场景,目的是让服务器知道是谁发出的请求。
如果请求了接口进行登录,服务端验证通过后会在响应头上加上Set-Cookie字段,等下次再发请求的时候,浏览器会自动将cookie附加在http请求的头字段cookie中,服务器就知道这个用户已经登录过了。
引用别人发的一个场景:

1.你准备去清空你的购物车,于是打开了买买买网站www.maimaimai.com,然后登录成功,一看,购物车东西这么少,不行,还得买多点。
2.你在看有什么东西买的过程中,你的好基友发给你一个链接www.nidongde.com,一脸yin笑地跟你说:“你懂的”,你毫不犹豫打开了。
3.你饶有兴致地浏览着www.nidongde.com,谁知这个网站暗地里做了些不可描述的事情!由于没有同源策略的限制,它向www.maimaimai.com发起了请求!聪明的你一定想到上面的话“服务端验证通过后会在响应头加入Set-Cookie字段,然后下次再发请求的时候,浏览器会自动将cookie附加在HTTP请求的头字段Cookie中”,这样一来,这个不法网站就相当于登录了你的账号,可以为所欲为了!如果这不是一个买买买账号,而是你的银行账号,那……
这就是传说中的CSRF攻击[浅谈CSRF攻击方式](http://www.cnblogs.com/hyddd/archive/2009/04/09/1432744.html)。

看了这波CSRF攻击我在想,即使有了同源策略限制,但cookie是明文的,还不是一样能拿下来。于是我看了一些cookie相关的文章聊一聊 cookieCookie/Session的机制与安全,知道了服务端可以设置httpOnly,使得前端无法操作cookie,如果没有这样的设置,像XSS攻击就可以去获取到cookieWeb安全测试之XSS;设置secure,则保证在https的加密通信中传输以防截获。

没有同源策略限制的DOM查询(引用)

1.有一天你刚睡醒,收到一封邮件,说是你的银行账号有风险,赶紧点进www.yinghang.com改密码。你吓尿了,赶紧点进去,还是熟悉的银行登录界面,你果断输入你的账号密码,登录进去看看钱有没有少了。
2.睡眼朦胧的你没看清楚,平时访问的银行网站是www.yinhang.com,而现在访问的是www.yinghang.com,这个钓鱼网站做了什么呢?

// HTML
<iframe name="yinhang" src="www.yinhang.com"></iframe>
// JS
// 由于没有同源策略的限制,钓鱼网站可以直接拿到别的网站的Dom
const iframe = window.frames['yinhang']
const node = iframe.document.getElementById('你输入账号密码的Input')
console.log(`拿到了这个${node},我还拿不到你刚刚输入的账号密码吗`)

同源策略能规避一些危害,但并不是说有了同源策略就完全安全了,只能说同源策略是浏览器最基本的安全机制。

哪些不支持跨域

三个允许跨域的标签

为什么要实现跨域呢

前端与后端放在不同的服务器上,就得跨域

如何实现跨域

说明:

  1. 如果是协议和端口造成的跨域,前端是无法解决的。
  2. 在跨域问题上,是根据域名端口协议是否匹配来识别,而不会根据域名对应的IP地址来判断。

请求跨域到底发出去请求了没有?

事实上,即便是跨域了,浏览器请求能发送出去,服务器能接收到请求并返回正确的结果,只是这个结果被浏览器拦截了。

跨域是为了阻止读取到另一个域名下的内容,Ajax可以获取响应,但浏览器认为这不安全,所以就把响应拦截住了。

jsonp方式实现跨域

  1. jsonp的原理
    利用<script>标签没有跨域限制的原理,网页可以得到从其他来源动态产生的json数据。
    创建一个script标签,把文件引进来

  2. jsonp和Ajax的区别
    jsonp和Ajax都是客户端向服务器发送请求,从服务器获取数据。但是Ajax属于同源策略,jsonp属于非同源策略(可以跨域)。

  3. jsonp的缺点

    1. 只支持get请求,不支持post,delete,put请求
    2. 不安全,容易受到xss攻击
    3. 现在很多网站都不采用jsonp的方式了
  4. jsonp示例
    index.html请求百度的数据。

<script>
  function show(data){
    console.log(data);
  }
</script>
<script src="https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=有钱&cb=show"></script>  
  1. 封装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}
    let arrs = [];
    for(let key in params){
      arrs.push(`${key}=${params[key]}`)
    }
    script.src = `${url}?${arrs.join("&")}`
    document.body.appendChild(script)
  })
}

jsonp({
  url: "https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su",
  params: {
    wd: '花'
  },
  cb: "show"
}).then(data => {
  console.log(data);
})

cors方式实现跨域

cors是目前开发中最常用的跨域解决方案
cors的安全性比较高,只要在服务器端做出修改,就可以实现跨域。

服务端设置Access-Control-Allow-Origin可以开启CORS,这个属性表示哪些域名可以访问资源,如果写成"*",允许任何源都可以访问。

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

参考

https://segmentfault.com/a/1190000015597029

https://juejin.im/post/5c23993de51d457b8c1f4ee1

上一篇下一篇

猜你喜欢

热点阅读