跨域,这是每个前端开发都会遇到的问题,确实,这是一个很头疼的问题,你说好好的调个接口你告诉我跨域了,那是谁在搞事情呢?其实你只要用其他非浏览器在去调用接口,就不会碰到跨域的问题了,其实这是浏览器同源策略在搞事情。浏览器对这个可是有理由的:“同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。”虽然说得这么官方,但其实通过这么一句话,这是一个安全机制,那为啥需要这个一个安全机制呢?首先在浏览器操作中有两大危险场景,一是针对接口的请求,二是针对Dom的查询。假设浏览器没有同源策略。
假设没有同源策略限制
接口请求:在浏览器中,我们做开发的都知道,有一玩意cookie估计大家都玩过,他主要用来存储一些信息,首先最主要的当然是用来处理登录场景,目的是让服务器端知道是谁发出的请求,假如你请求进行登录,那么服务器端验证通过后就会在相应头假如Set-Cookie字段,然后在下一次在发出请求的时候,浏览器自动就会将cookie附加到Http请求的头字段Cookie中,那服务器就晓得你登录过了。好,知道这个流程后。我们来看一个场景:
1 你打开某宝正在瞅瞅想买个那个啥,正在乐滋滋的逛啊逛,从这个页面点到那个页面。
2 正在你逛的时候,突然有一个美女头像的不认识的好友给你发一个不可描述的链接,然后你口水直流,毫不犹豫打开了。
3 你很兴奋地浏览这个不可描述的链接打开的网址,然后这个网址就悄悄地又做了些不可描述的事情!它像你之前浏览的某宝发起了请求,由于没有同源策略的限制,服务端在验证通过后在响应头加入Set-Cookie字段,然后下次再发请求的时候,浏览器会自动将cookie附加在HTTP请求的头字段Cookie中”,这样一来,这个不法网站就相当于登录了你的账号,可以为所欲为了!这就是传说中的CSRF攻击,那你会想,即使有了同源策略限制,但cookie是明文的,还不是一样能看到。其实在Cookie/Session的机制与安全中,服务端可以设置httpOnly,使得前端无法操作cookie,如果没有这样的设置,像XSS攻击就可以去获取到cookieWeb安全测试之XSS;设置secure,则保证在https的加密通信中传输以防截获。
Dom查询:由于没有同源策略的限制,那钓鱼网站就可以直接获取到其他网站的dom, 这样的话又可以干很多不可描述的事了,首先他将某宝的登录页面放到一个iframe中,然后伪装成某宝,你不注意在这个钓鱼网站上登录你的账号密码的时候就中招了。由此我们知道,同源策略确实能规避一些危险,不是说有了同源策略就安全,只是说同源策略是一种浏览器最基本的安全机制,毕竟能提高一点攻击的成本。其实没有刺不穿的盾,只是攻击的成本和攻击成功后获得的利益成不成正比。现在很多网站对这个安全性也提示了很多,就算你获取了登录账号密码,有时候还要手机验证码验证,像某宝,如果相差时间很短但在两个地区登录也考虑到了,所以只能说同源策略是一种浏览器最基本的安全机制,但如果只靠这种机制的话也不太现实。
跨域的情况
这时候我们知道同源策略确实是浏览器做的一件好事,用来防御那些小人干不可描述的事情,但像我们这种正人君子不应该被拒之门外呀。其实只要我们打开防止正确,就应该可以跨域了。首先我们来看看跨域的几种情况:
跨域的解决方式: jsonp
在HTML标签里,一些标签比如script、img这样的获取资源的标签是没有跨域限制的,利用这一点,我们可以这样干:
那前端就可以这么干了:
跨域的解决方式: 空iframe加form
本质上script加载资源只能是GET方法,所以JSONP只能发GET请求,那么如果要发POST请求怎么办呢?
跨域的解决方式: CORS
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing),CORS有两种请求,简单请求和非简单请求。
简单请求
只要同时满足以下两大条件,就属于简单请求。
(1) 请求方法是以下三种方法之一:HEAD, GET, POST
(2)HTTP的头信息不超出以下几种字段:Accept, Accept-Language, Content-Language, Last-Event-ID, Content-Type只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain这三个值。
后端:
非简单请求
不属于简单请求的就属于非简单请求。非简单请求会发出一次预检测请求,返回码是204,预检测通过才会真正发出请求,这才返回200。这里通过前端发请求的时候增加一个额外的headers来触发非简单请求。
来源:https://blog.csdn.net/bobo79888/article/details/99318976