为了保证用户数据的安全性、避免中间运营商的劫持,部署 https 已成当务之急。https 早已不是锦上添加的可有可无项,它已经逐渐成为 WEB 服务的标配。那么什么是 https 呢,https 与 http 的区别在哪儿,我们作为前端在部署 https 时应该注意什么呢?
1. http 与 https 的区别 #
我们传统使用的 http 是 http1.0,是基于 TCP/IP 的应用层协议,浏览器的每次请求都需要与服务器建立一个 TCP 连接,服务器完成请求处理后立即断开 TCP 连接,服务器不再跟踪之前的请求。这种方式优点是:
- 通信开销小,简单快速,传输成本低;
- 使用灵活,允许传输任意类型或数据格式的对象,传输的类型由 Content-Type 标记
但 http 还有着更明显的缺点,导致使用 http 协议的不安全:
- 使用明文(不加密)的方式进行传输,内容容易被窃听和获取;
- 不验证通信方的身份,有可能遭遇伪装;
- 无法验证明文的完整性,有可能被篡改
正是因为 http 存在着不足的地方,才需要一个更安全的协议来保证数据在传输过程中安全。https=http+加密+认证+完整性保护
,https 就是 http 的安全升级版。
HTTPS 是运行在 SSL/TLS 之上的 HTTP 协议,SSL/TLS 运行在 TCP 之上。所有传输的内容都经过加密,加密采用对称加密。
https 报文中的任何东西都被加密,包括所有报头和荷载。一个攻击者所能知道的只是两者之前有一个连接而已。
2. 运营商劫持 #
在我们通常使用的 http 协议里,信息都是使用明文的方式传输的,那么中间的运营商就有可能在信息上做手脚。
运营商劫持主要有三种方式:
- DNS 劫持:又叫 DNS 重定向攻击,将用户到想到非预期网站的行为,主要是通过修改用户的 DNS 解析结果实现
- url 劫持:
- 302 跳转劫持,将用户 url 重定向到非目标网站
- 修改 url 参数,比如在 url 里添加流量渠道标识或者页面参数
- 网页内容篡改
- 直接在网页中插入 js
- 在网页中嵌入 iframe
万一在遇到运营商劫持的情况时,有哪些应对方案呢
- 投诉增值业务部门进而投诉工信部
- 绕过运营商的 localDNS,使用公共的 DNS
- 抛弃域名访问方式,直接通过 IP 访问
- https:https 只能解决连接劫持,无法解决 DNS 劫持
3. SPDY #
SPDY 是 google 开发的基于传输控制协议(TCP)的应用层协议,SPDY 协议旨在通过压缩、多路复用和优先级来缩短网页的加载时间和提高安全性。(SPDY 是 speedy 的昵音,意为更快)
SPDY 与 http 的关系:
SPDY 协议只在性能上对 http 做了很大的优化,其核心思想是尽量减少连接个数,而对于 http 的语义并没有做太大的修改。具体来说是,SPDY 使用了 HTTP 的方法和页眉,但是删除了一些头并重写了 HTTP 中管理连接和数据转移格式的部分,所以基本上是兼容 HTTP 的。 HTTP 的 GET 和 POST 消息格式保持不变,即现有的所有服务端应用均不用做任何修改。
SPDY 协议的优点:
- 多路复用 请求优化: 在一个连接内可以有多个请求,通过复用在单个 TCP 连接上的多次请求,而非为每个请求单独开放连接
- 支持服务器推送技术: 服务器可以主动向客户端发起通信向客户端推送数据,这种预加载可以使用户一直保持一个快速的网络。
- 压缩了 http 头: 舍弃掉了不必要的头信息,经过压缩之后可以节省多余数据传输所带来的等待时间和带宽
- 强制使用 SSL 传输协议: Web 未来的发展方向必定是安全的网络连接,全部请求 SSL 加密后,信息传输更加安全。
4. 在迁移到 https 的过程中,我们应该做些什么 #
在 https 的页面里,是不能有 http 链接存在的,在 chrome 下依然会请求服务器,但会在控制台给出警告;在 firefox 下直接拒绝请求,可能会知道页面混乱或报错。
因此,在 https 的页面里,我们要确保所有的内部链接全部指向 https,确保已经在页面到页面级别制定了新的 https 网址。
具体的操作是:
- 所有的链接指向 https,或者不明确协议,用//开头,则请求资源的协议与页面相同
- 如果页面中依然还有 http 的链接,可以在头部添加此 meta 头,自动将 http 资源替换成 https 请求:
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests" />
- 所有的静态资源(js, css ,img 等)均需上传至 CDN 域名下:img1.gting.com 和 mat1.gtimg.com
我们尽量保证 https 页面里不含有 http 的链接,但是人工检查难免有疏漏的,因此写了一个 js 脚本用来检测页面中 http 连接的数量:
(function () {
var tags = ["link", "script", "img", "audo", "video", "frame"], // 遍历的资源
host_protocol = window.location.protocol.replace(":", ""), // 当前页面的协议
flag = true; // 是否打开上传
if (host_protocol == "https" && flag) {
var a = document.createElement("a"),
result = "";
for (var i = 0, len = tags.length; i < len; i++) {
var item = document.getElementsByTagName(tags[i]),
num = 0;
for (var j = 0, t = item.length; j < t; j++) {
var c = item[j];
var url =
c.getAttribute("href") || c.getAttribute("src") || c.href || c.src;
if (url) {
a.href = url;
var protocol = a.protocol.replace(":", "");
// var protocol = url.substr(0, 5);
if (protocol == "http") {
num++;
}
}
}
num && (result += tags[i] + "=" + num + "|");
}
result = result.substring(0, result.length - 1);
// console.log( result );
// console.log( encodeURIComponent(result) );
var img = new Image();
img.src = "http://www.qq.com/s.gif?q=" + encodeURIComponent(result);
img.onload = img.onerror = function () {
img = null;
};
}
})();
这个脚本能在页面加载完成后,扫描页面中的资源,检测其链接是否为 http 类型,且只在 https 的页面中,开关打开的情况下才运行,统计各个资源里 http 的个数。不过更详细的信息还不太好获取到,比如:链接为 http 类型的资源在页面中的第几行,ajax 请求的链接等信息。
5. http2 展望 #
HTTP/2 主要基于 SPDY 协议,不过还是有区别的, http/2 支持明文 http 传输,而 SPDY 强制使用 https。 HTTP/2 采用二进制格式传输数据,而非 HTTP/1.x 的文本格式。二进制格式在协议的解析和优化扩展上带来更多的优势和可能。
http2 特点是:
- 多路复用:与 SPDY 类似,这样,就省掉了多次建立连接的时间,这个时间对 TLS 尤其明显,因为 TLS 连接费时间
- 加速 TLS 交付:HTTP/2 只需一次耗时的 TLS 握手,并且通过一个连接上的多路利用实现最佳性能。HTTP/2 还会压缩首部数据
- 简化 web 应用,适合内容混杂的页面: 用 HTTP/2 可以让 Web 开发者省很多事,因为不用再做那些针对 HTTP/1.x 的优化工作了
- 更安全: 通过减少 TLS 的性能损失,可以让更多应用使用 TLS,从而让用户信息更安全
那么在未来的 http2 下,我们前端需要做些什么呢?
- 减少 http 请求不一定提升性能: 减少 http 请求的前提是资源的合并,导致单个文件的体积变大,根据测试表明,在 http2 的环境下,合并为一个大文件的加载时间反而会比不合并更长
- 压缩仍然需要:毕竟获取一个小文件的时间比大文件更短,http2 并不会帮你自动压缩文件。HTTP/2 目的之一,就在于想把开发环境与生产环境的部署尽量保持一致,减少因为打包合并而产生一些不必要的麻烦
- 未来将更专注与页面本身而非性能:http2 从页面加载速度,资源请求,安全性等做很多的工作,让我们更加专注于页面功能上的实现。
如果还有什么不足,欢迎指出批评,谢谢。