静态资源https可用性检测
缘起
随着国内网络环境的持续恶化,各种篡改和劫持层出不穷,越来越多的网站选择了全站 HTTPS。HTTPS 通过 TLS 层和证书机制提供了内容加密、身份认证和数据完整性三大功能,可以有效防止数据被查看或篡改,以及防止中间人冒充。
在可见的未来,HTTP2 只在 HTTPS 环境下被支持,iOS9 要求应用程序必须采用 HTTPS 传输,升级HTTPS迫在眉睫。
实现
大概8-9月份的时候,在前端leader的主导,运维协助的情况下,M站已经基本完成HTTPS的升级;有了上次的技术摸底,这次APP全部升级HTTPS就显得顺风顺水了很多;接下来是今天的重点:测试静态资源https可用性检测。
静态资源https可用性检测
需求
对静态资源https的支持程度做统计
-
记录IP粒度的地域信息;
-
对所有域名(静态文件所有域名)进行测试;
-
劫持,内容是否一致;
分析
需求1中提到的记录IP粒度的地域信息,在服务器端很容易就能获取到;
需求2和3需要前端提供每个域名下的返回状态,以接口的方式传给后端,和1整合后统一存入数据库中
前端实现方案
-
图片所有域名需要返回加载状态
-
js或css文件所有域名需要返回加载状态外,还需要对比是否被劫持
-
图片和js统一返回状态
-
将返回状态存入data中,以便后端调用
返回所有域名下js文件访问状态
function returnJsStatus(callback) {
var domainStatus = {},
domain = ['static01', 'static02'],
i;
for (i = 0; i < domain.length; i = i + 1) {
var xhr = new XMLHttpRequest();
xhr.open('GET','https://' + domain[i] + '.zepto/1.0.0/zepto.min.js');
xhr.onload = (function (index) {
return function () {
if (xhr.responseText.length !== 25768) {
domainStatus[domain[index]] = -200;
} else {
domainStatus[domain[index]] = xhr.status;
}
if (count(domainStatus) === domain.length) {
callback(domainStatus);
}
}
})(i);
xhr.send();
}
}
返回所有域名下同一张图片访问状态
function returnImgStatus(callback) {
var domainStatus = {},
imgArr = [],
domain = ['pic01', 'pic02', 'pic03', 'pic04', 'pic05'],
i;
for (i = 0; i < domain.length; i = i + 1) {
imgArr[i] = new Image();
imgArr[i].src = 'https://' + domain[i] + './img/default-avatar.png';
imgArr[i].onload = (function (index) {
return function () {
domainStatus[domain[index]] = 200;
if (count(domainStatus) === domain.length) {
callback(domainStatus);
}
}
})(i);
imgArr[i].onerror = (function(index){
return function () {
domainStatus[domain[index]] = 404;
if (count(domainStatus) === domain.length) {
callback(domainStatus);
}
}
})(i);
}
}
将以上返回状态,存入data中,方便后端调用
var data = {};
function result () {
if (data.js && data.img) {
console.log(data);
//最终返回的结果格式如下:
/*
{
img:{ pic01: XXX, pic02: XXX, pic03: XXX, pic04: XXX, pic05: XXX },
js:{ static01: XXX, static02: XXX }
}
*/
}
}
function init() {
returnJsStatus(function (status) {
data.js = status;
result();
});
returnImgStatus(function (status) {
data.img = status;
result();
});
}
init();
上面用到的获取对象长度的方法
function count(o){
var t = typeof o,
n,
i;
if (t === 'object') {
n = 0;
for(i in o){
n++;
}
return n;
}
return false;
};
当然最终返回的数据格式需要和后端合作人员确定api后,转成对应格式,配合使用
升级HTTPS可参考如下: