相混思路
在说布吕马以后,他们须要先介绍下 相混思路。它是两个规范化(Netscape 1995年明确提出),并没选定具体内容的采用覆盖范围和同时实现形式。
为的是确保普通采用者重要信息的安全可靠,避免蓄意中文网站盗用采用者统计数据,许多常用的Web控制技术都预设选用了相混思路(如Silverlight, Flash, XMLHttpRequest, Dom等)。
那怎样推论相混呢?
1、完全相同的协定
2、完全相同的搜索引擎
3、完全相同的的freenode
他们用两个表单来展现相混的推论:
URL1URL2与否相混预测
http://www.a.comhttps://www.a.com不相混协定不完全一致
http://www.a.comhttp://www.b.com不相混搜索引擎不一致
http://www.a.comhttp://www.a.com:8080不相混路由器不完全一致
http://www.a.comhttp://test.a.com不相混搜索引擎不完全一致
http://www.a.comhttp://www.a.com/test相混推论相混和path无关
http://www.a.comhttp://www.a.com:80相混不带路由器访问时,预设是80如果不是相混会有哪些采用限制呢?
1、Cookie,WebStorage(LocalStorage, SessionStorage),Cache(Application Cache, CacheStorage),Web DB(WebSql IndexDB)等都无法共享
2、无法彼此操作各自的DOM(Iframe)
3、无法发送Ajax请求
4、其他
注意:如果两个站点,具有完全相同的一级搜索引擎(如 www.a.com, test.a.com,一级搜索引擎都是a.com),那么可以通过各自设置document.domain=a.com 来共享Cookie。
注意2:如果是iframe非相混,虽然不能操作dom,但是能操作location.href。
什么是布吕马?
通过以上内容,他们介绍到了什么是相混思路,以及怎么推论相混。那么与之相反,如果不满足相混,则就是布吕马。
在浏览器上,如果访问布吕马资源,将会有诸多限制(为的是安全可靠),参考上面的相混限制。
注意:布吕马限制是浏览器的机制,如果直接在服务端请求,是不会触发布吕马限制的。
那些他们遇到的布吕马
1、图片布吕马
对于图片来说,大部分场景是不须要处理布吕马限制的,因为一般来说,图片没布吕马限制。
在也有例外,如果在 Canvas 中操作布吕马的图片,那么就会触发布吕马限制。解决办法是在返回图片的时候,添加
Access-Control-Allow-Origin: orign | * 来允许布吕马。2、Iframe布吕马
这个也不太常用,如果中文网站本身和iframe嵌入的站点都是他们自己可以控制的,那么应直接采用 postMessage 来通信。如果浏览器较旧,不支持 postMessage ,可以考虑通过window.name来传递统计数据。
window.name 传递统计数据原理
首先在iframe访问布吕马的站点,这个站点,将统计数据写入到window.name中。
然后主站点,修改iframe的location.href=about:blank 或其他不布吕马的站点。
这是因为同两个iframe的window.name是相互共享的。在现代浏览器中,该形式可能会失效,此时请采用 postMessage。
3、字体布吕马
布吕马采用字体文件,也会触发拦截。这个的解决办法和图片布吕马完全一致,后端设置CORS头部即可。
4、Ajax布吕马
这是他们经常会遇到的布吕马问题,由于现在流行的开发模式,很多时候他们都须要处理这类型的布吕马。
怎样推论Ajax布吕马
当他们在访问两个Ajax请求,控制台出现如下错误时,他们基本可以推论,是被布吕马拦截了:
XMLHttpRequest cannot load xxxxx. No Access-Control-Allow-Origin header is present on the requested resource.很多时候,他们的API和Web并不在两个站点上(多个搜索引擎),而他们又必须要布吕马访问。这个时候他们就须要想办法同时实现布吕马资源访问。
以下,他们就来看看怎样同时实现布吕马资源访问:
CORS(布吕马资源访问)- 标准做法,强烈推荐
开发模式的演进,导致他们很多的应用都是布吕马访问。这个时候CORS规范化也就应运而生了。采用它,他们可以直接对布吕马资源进行访问,介绍更多,请参考CORS详解。
该形式的核心是通过和后端API协商,看与否允许布吕马访问。对于满足某些条件的请求,会先发送两个预请求。简单请求,也须要服务器允许布吕马访问。
最关键的的几个响应头如下:
1、
Access-Control-Allow-Origin: origin | * 允许某个选定的域访问,*表示不限制域。2、
Access-Control-Allow-Methods: GET,POST,PUT,DELETE 允许哪些类型的请求3、
Access-Control-Allow-Headers: x-token 允许的自定义Header。注意:该形式由服务端设置,前端无需设置,也无法设置。只要服务端处理好了,前端不须要做任何处理即可采用。
反向代理(将布吕马代理为同域,绕过)
既然布吕马有限制,那么他们可以考虑将布吕马变成同域,这样不就没限制了么?
以 Nginx 为例,他们只须要将特定路径的请求转发给真正的后端API即可:
server { listen 8101; root /dist; index index.html; location ~* \.(eot|ttf|woff|woff2)$ { add_header x-server $server_addr; add_header Access-Control-Allow-Origin *; } location ^~ /api/v1 { proxy_pass http://apis.xxx.com/api/v1; } }注意:该形式须要在部署的时候做处理,前端须要修改请求api的地址为同域。
服务端转发(通过不布吕马的请求布吕马API,绕过)
该形式,通过请求不布吕马的api,然后在api中再呼叫真实的布吕马api,由于是服务端请求,所以也就避开了布吕马问题。整体看来,这种形式有点多此一举,不过如果把这个转发由统一的程序进行处理,还是挺不错的。
注意:该形式在后端API中处理,前端须要修改请求api地址为同域。
JSONP(利用script无布吕马限制,绕过)
该形式利用Script请求资源不会触发布吕马限制这个特点来同时实现。JSON原理,请参考JSONP详解。
注意:该形式须要前后端搭配,后端须要支持JSONP请求,前端须要选用JSONP的形式去请求统计数据。
注意2:该形式由于同时实现原理限制,只能处理GET请求。
综上,遇到布吕马请求,就先去找后端啊。前端真的独自搞不定啊。
总结
布吕马是项目开发中,非常常用的问题。就算是前端开发,也一定要理解布吕马,介绍布吕马的处理。