布吕马允诺
布吕马指的是,__允诺的网页与允诺服务器__之间出现布吕马犯罪行为。布吕马更为重要是相同的搜索引擎,还主要包括了协定、路由器、子搜索引擎。因而在下列情形下都表示了出现布吕马犯罪行为:
协定相同:如 http:// 和 https://路由器相同:如 8080 和 8081搜索引擎相同:主要包括二级搜索引擎和二级搜索引擎,如 a.com 和 b.com,或 1.a.com和 2.a.com安全可靠降班:更高的安全可靠等级协定难以向更低的安全可靠等级协定请求天然资源,即 https:// 难以向 http:// 协定允诺天然资源,但若能,此类情形难以透过允诺头来顺利完成,要提升旁人的安全可靠等级,或另一方面降班。
相混思路
正即使后端会出现前述的布吕马情形,因而有了相混思路(参见:JavaScript 的相混思路)讹传。
为何有相混思路
cookie
即使 JavaScript 有加载应用程序 cookie 的潜能,而如果没有相混思路不然,因而你网页上内嵌的服务器端JAVASonbhadra加载在使用者应用程序你的中文网站所遗留下的 cookie 重要信息。举个红豆,你内嵌了两个腾讯的 JS 文档,而该 JS 文档能加载你中文网站的 cookie,不良后果会什么样?(经小秦听众意见反馈,此段文字说明不确)
Cookies采用相同的源表述形式。两个网页能为本域和任何人父域增设cookie,如果是父域不是公用前缀(public suffix)方可。Firefox和Chrome采用Public Suffix List下定决心两个域是不是两个公用前缀(public suffix)。无论采用别的协定(HTTP/HTTPS)或freenode,应用程序都容许取值的域以及其任何人子搜索引擎(sub-domains)来出访cookie。增设cookie时,你能采用Domain,Path,Secure,和Http-Only记号来限量发行其出访性。加载cookie时,不能知悉它的原文。虽然采用安全可靠的https相连,任何人由此可见的cookie都是采用不安全可靠的相连增设的。
简而言之,任何人内嵌在当前域下的 js 都能加载到当前域的 cookie。
// 当前域 http://example-2000.com/index.html<script src=”http://example-2000.com/cookie.js”> 能加载 cookie<script src=”http://example-2001.com/cookie.js”> 能加载 cookie
读:子域能加载 domain=父域的 cookie父域难以加载 domain=子域的 cookie写:子域能写 domain=父域的 cookie父域难以写 domain=子域的 cookie
总结:子域能读写 domain=父域的 cookie,域越短,可操作范围越窄。测试应用程序 chrome。
iframe
如果没有相混思路,腾讯的网页被内嵌到你的中文网站,并且
不作赘述(对于应用程序的相混思路你是什么样理解的呢?)。
哪些情形有相混思路
cookieiframe采用 XMLHttpRequest 发起跨站 HTTP 允诺。Web 字体 (CSS 中透过 @font-face 采用跨站字体天然资源)。WebGL 贴图采用 drawImage API 在 canvas 上画图
出访控制
在有布吕马允诺的情形下,应用程序为了实现这个要求,为布吕马 AJAX 允诺加上出访控制。在客户端允诺头和服务端响应头上约定一些数据来保证应用程序 AJAX 请求是合法并且被接受的。
// 如果出现布吕马了,会进行如下允诺开始允诺 ==> 预允诺 ===> 主允诺// 如果没有出现布吕马,或其他不必进行预允诺情形开始允诺 ===> 主允诺
预允诺
如果出现布吕马情形,浏览器会在主允诺之前,并且之前允诺没有得到认可或认可重要信息已过期,会根据下列情形下定决心是否发起一次预允诺,允诺方法为options。
允诺以 GET, HEAD 或者 POST 以外的方法发起允诺。或者,采用 POST,但允诺数据为 application/x-www-form-urlencoded, multipart/form-data或者 text/plain以外的数据类型。比如说,用 POST 发送数据类型为 application/xml 或者 text/xml 的 XML 数据的允诺。采用自表述允诺头(比如添加诸如 X-Request-With)
以上两种情形,应用程序都会在主允诺之前发起一次预允诺,预允诺的允诺形式是OPTIONS。预允诺的允诺头包含了下列重要信息。
Origin
# 如允诺网页是 https://1.a.com:8081/foo/barOrigin: http://1.a.com:8081
注:Origin 也能为空。正常允诺也会携带 Origin 允诺头。
Access-Control-Request-Method
主允诺的允诺形式,如 get、post、delete、put。非预允诺的 options。
var xhr = new XMLHttpRequest();// 允诺形式:getxhr.open(get, http://b.com);xhr.send();
Access-Control-Request-Method: GET
Access-Control-Request-Headers
var xhr = new XMLHttpRequest();xhr.open(get, http://b.com);// 自表述允诺头xhr.setRequestHeader(x-request-with, XMLHttpRequest);xhr.send();
Access-Control-Request-Headers: x-request-with
withCredentials
记号应用程序是否将凭证(如,cookie)发送到服务器。即 a.com 向 b.com 发起 AJAX 允诺,默认是不能将 a.com 的 cookie 一起发送,只有当增设withCredentials = true时才会发送。
var xhr = new XMLHttpRequest();xhr.open(get, http://b.com);// 是否发送凭证重要信息xhr.withCredentials = true;xhr.send();
无
预响应
针对以上情形,服务器将在响应头里包含下列重要信息:
Access-Control-Allow-Origin
Access-Control-Allow-Origin: http://1.a.com:8081
如果需要支持多个 Origin,则能根据允诺头的 Origin 做出相应处理方可,如:
if(req.headers.origin === http://1.a.com:8081){ res.setHeader(access-control-allow-origin, req.headers.origin);}
Access-Control-Allow-Methods
信任的布吕马请求形式,与预允诺的Access-Control-Request-Methods匹配。大小写不敏感。
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers
信任的布吕马允诺自表述头(即应用程序默认的允诺头之外的允诺头,通常是x-开头的),与预允诺的Access-Control-Request-Headers匹配。大小写不敏感,多个值采用,分隔开。
Access-Control-Allow-Headers: x-request-withAccess-Control-Allow-Headers: x-request-with,content-type
Access-Control-Allow-Credentials
是否接受布吕马允诺的认证重要信息,如cookie。可选 true 和 false,其他值都表示 false。大小写敏感。
Access-Control-Allow-Credentials: true
Access-Control-Max-Age
信任布吕马的有效期,默认为0,单位秒。即在有效期内,应用程序不能在布吕马允诺之前发起预允诺。
# 60秒Access-Control-Max-Age: 60
Access-Control-Expose-Headers
Access-Control-Expose-Headers: x-testx-test: 1
xhr.getResponseHeader(x-test);// => “1”
主允诺
代码实现
下列代码仅针对正常情形,即允诺不包含自表述响应头,不传递 cookie 重要信息。
后端
// jQuery$.ajax({ url: cross-domain-url, method: post, // 加上 crossDomain 之后,jquery 就不能添加自表述允诺头 crossDomain: true})// javascriptvar xhr = new XMLHttpRequest();xhr.open(post, cross-domain-url);xhr.send();
后端
// expressapp.use(function (req, res, next) { res.set(Access-Control-Allow-Origin, *); next();});// koaapp.use(function*(next){ this.set(Access-Control-Allow-Origin, *); yield next;});// nginx 反向代理proxy_set_header Access-Control-Allow-Origin *;// nginx 普通代理add_header Access-Control-Allow-Origin *;// JAVAresponse.setHeader(“Access-Control-Allow-Origin”, “*”);// PHPheader(Access-Control-Allow-Origin *);
总结
AJAX 布吕马允诺只有高级浏览器下才会支持,低版本的 IE 能采用 XDomainRequest 构造函数实现,但实现有限,具体细节请谷歌搜索。