开完组会,OKOK!继续复习!今天来复习下跨域这块儿的一些问题吧.
说到跨域,那么就掰扯掰扯同源起.
同源策略:
同源,需要协议,域名以及端口都相同.其目的是为了保障用户的信息安全,防止恶意网站窃取数据.
我们来举个例子吧:
对于网站http://www.excce.com/dir/page.html,协议是http://,域名是www.excce.com,端口是80.那么下面这些是否为同源呢?
http://www.excce.com/dir1/concat.html(同源)
http://excce.com/dir/page.html(不同源,域名不同)
https://www.excce.com/dir/page.html(不同源,协议不同)
http://www.excce.com:81/dir/page.html(不同源,端口不同)
那么,我们接下来来说下,非同源有哪些操作会被限制?
1.Ajax的请求不可发送
2.DOM的读取
3.localstorage,cookie以及IndexDB无法获取
那么,有哪些又不会被非同源给限制操作呢?
1.重定向
2.表单form的提交
3.页面中的链接
4.跨域资源引入,js可加载但是不可读写内容,比如:<script src="..."></script>、<img>、<iframe>、<link>。
注意,若在标签里加入crossOrigin属性,并且服务器允许跨域后,会得到精确的报错消息;若是服务器不允许跨域,就会被同源策略阻止加载资源。若是不添加这个属性,只能知道报错,不知道具体信息。
注意,上述的这些特点,这对于我们接下来说的跨域,有很重要的铺垫哈哈.
接下来,我们来讲述下前端的几种常用的跨域方式:
1.JSONP
JSONP的话,主要就是利用了script标签没有跨域限制的这个特性来完成的.它的理念就是,与服务端约定好一个回调函数名,服务端接收到请求后,将返回一段JS,在这段JS代码中调用了约定好的回调函数,并且将数据作为参数进行传递.当网页接收到这段JS代码后,就会执行这个回调函数,这时数据已经成功传输到客户端了.当然,它有个缺点就是它只能够用get方式,如果要使用完整的rest接口的话,那还是用cors.
接下来,我们来看看cors
2.CORS
CORS是一种机制,它使用额外的http头来告诉浏览器让运行在一个origin上的web应用被准许访问来自不同源的资源.它允许浏览器向跨源服务器发送XMLHttpRequest请求,从而克服Ajax只能同源使用的限制.CORS通信与同源的ajax没什么差别,浏览器一旦发现ajax请求跨域,就会自动添加一些附加的头,有时还会多出一次附加请求.因此实现CORS通信的关键是服务器,只要服务器实现了CORS接口,就可以跨源通信.
1.get,head,post
2.人为设置一下集合外的请求头:accept,accept-language,content-language,content-type,last-event-id,content-type
var xhr= new XMLHttpRequest(); xhr.withCredentials = true;
否则,即使服务器同意发送Cookie,浏览器也不会发送.或者,服务器要求设置Cookie,浏览器也不会处理.需要注意一点,如果要发送Cookie,Access-Control-Allow-Origin就不可以设置为星号了,必须必须指定明确的,与请求网页一致的域名.
3.window.postMessage
这个方法可以安全地实现跨源通信,通常两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议,端口号,以及主机时,这两个脚本才能相互通信.
4.document.domain+Iframe
该方式只能用于二级域名相同的情况下,比如a.ces.com与b.ces.com就可以用在这里.
5.window.location.hash + Iframe
原理就是通过url带hash,通过一个非跨域的中间页面来传递数据.
比如有a.html,b.html以及c.html,a与b是同域的,比如都是http://local:8000,c.html是http://local:8081.整个流程的话呢,一开始a.html给c.html传一个hash值,然后c.html将收到的hash值给b,最后n.html将结果放到a.html的hash值中.
6.window.name+Iframe
window对象的name属性是一个很特别的属性,当该window的location变化,然后重新加载,它的name属性可以依然保持不变.
既然前面,提到了Ajax跨域带Cookie的问题,我们就来跟着简单复习下Cookie,localstorage以及sessionstorage.
Cookie是存储在用户本地终端上的数据,它的大小限制为4KB左右,有时候也用Cookie让网站辨别用户身份.它可以设置失效时间,默认是关闭浏览器后就失效了,它每次都会携带再HTTP请求头中,若使用cookie保存过多数据会带来性能的问题.
localstorage的话是h5中新加入的技术,localStorage是存储在客户端中的,不参与与服务器的通信,它会永久性的保存,除非被清除,内存数据大小在5MB左右.sessionStorage与localStorage的接口类似,但是保存数据的生命周期却不相同.sessionStorage的话,只是可以将一部分数据在当前会话中保存下来,刷新页面数据依旧存下但当页面关闭后,sessionStorage中的数据就会被清空.
再简单说下应用场景吧:
因为每个HTTP请求都会带着Cookie的信息,因此Cookie当然是能多精简就多精简咯.我们常可以用到判断用户是否登陆,针对登陆过用户,服务器端会在他登陆时网Cookie中插入一段加密过的唯一辨识单一用户的辨识码,下次只要读取这个值就可以判断当前用户是否登陆过啦.
localStorage的话可以用于如HTML5游戏通常会产生一些本地数据.sessionStorage的话,如果遇到一些内容特别多的表单,我们可以把表单页面拆分成多个子页面,然后按步骤引导用户填写,这时候sessionStorage了.
需要注意一点,无论是什么数据都可以放在前三者中,但是使用它们的时候,需要注意,是否存在XSS注入的风险,只要打开控制台,随意修改它们值的时候,就可能会有XSS的风险.这里再啰嗦的说下前端的一些常见安全问题好啦.
1.XSS:
XSS是cross-site scripting,跨域脚本攻击.其攻击是指攻击者向web页面里插入恶意HTML标签或者JS代码.比如,攻击者在论坛中放入一个看似安全的链接来骗取用户cookie中的账密信息,或者在论坛中加入一个恶意表单来骗取用户而获取想要得到的信息.若要防范XSS的话,可以采取在代码里对用户输入的地方仔细检查并且对<script>、<img>、<a>等进行过滤,或者,把任何内容写到页面之前都必须进行编码,避免泄露htmltag.
2.CSRF
CSRF,即跨站点请求伪造,攻击者会诱导受害者进入第三方网站,在第三网站中向被攻击网站发送跨域请求,利用受害者在被攻击网站以获取的注册凭证,绕过后台用户的验证,达到冒充用户对被攻击的网站执行某项操作的目的.它的防范的话,可以用token方式,服务器给客户端表单一个token,客户端提交的表单中带着这个token,若返回的token不合法,则拒绝掉;或者隐藏令牌,把token藏在http的head中;或者Referer验证,指的就是页面请求来源,只接受本站的请求,服务器才做响应.
3.SQL注入
SQL注入,就是将SQL命令插入在web表单,输入域名或者页面请求的查询字符串,最终达到欺骗服务器执行恶意SQL命令的作用.防范的话,我们可以对用户的输入进行校验,可以使用正则表达式来限制长度.或者对机密信息进行加密,且不要使用管理员权限的数据库连接.