为什么http的内容不能在https内使用

1,974 阅读4分钟

作者:roku
github

背景:

该项目是由html, css, javascript, jquery工具编写的一款简单的网页游戏——2048。 最终项目文件分别为index.html,2048.css,main2048.js,support2048.js,animation2048.js 最终代码在被提交到GitHub之后将进行git page部署,以方便预览运行效果。

这里附上项目的源代码与自己的过程笔记(有兴趣的朋友也可以自己试试看):

代码:github.com/rokumeow/20…
运行效果:rokumeow.github.io/2048game/

问题:

该项目在本地VsCode中运行正常,但是在部署到git page上时,所有js文件均未加载,只有html文件与css文件加载成功,功能无法正常运行。

原因排查:

将所有js代码放入html文件的内置script标签内,再次运行。 运行结果依旧如上,但出现了错误提示:$符号为undefined,由此可知,js未能加载成功的原因是jquery库未能成功导入。

于是对jquery导入语句进行了检查:

 <script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.min.js"></script>

之前有看到过,建议在国内导入jquery库的话不要使用Google的链接,容易不稳定。但是该项目采用的是Microsoft提供的jquery链接,应该不会有链接不稳定这一类情况发生。

后来在同事的指点下,将该语句中的http修改为https后,发现jquery库可以正确导入了,js文件也能够正确的加载。 修改后的语句为:

 <script type="text/javascript" src="https://ajax.microsoft.com/ajax/jquery/jquery-1.4.min.js"></script>

深入思考

第一句jquery导入语句是从一个还算知名的教程网站上看到的,而且在VsCode本地也是可以运行的,但为什么在GitHub上部署的时候却会有协议上的问题呢?于是查找了很多相关资料,希望能够弄明白这个问题。

(以下内容摘自参考资料)

浏览器默认是不允许在 https 里面引用 http 资源的,一般都会弹出提示框。

询问提示框

用户确认后才会继续加载,用户体验非常差。而且如果在一个 https 页面里动态的引入 http 资源,比如引入一个 js 文件,会被直接 block 掉的。Chrome v21 之后,在 SSL 加密页面 embed 非 SSL 的 Flash 资源也会被默默的屏蔽掉,只留下一句 console 报告。

https是当下的网站的主流趋势,甚至像苹果这样的大公司,则完全要求用户必须使用https地址。   然而对于以前http链接来说,我们往往就存在一个兼容性问题,因为你不可能一下就全部切换过去,应该在很长一段时间内,https与http将共存。

*来源:blog.csdn.net/qq_38834352…


HTTPS与HTTP的安全性

为什么认为HTTPS协议安全而HTTP协议不安全呢?

http协议属于明文传输协议,交互过程以及数据传输都没有进行加密,通信双方也没有进行任何认证,通信过程非常容易遭遇劫持、监听、篡改,严重情况下,会造成恶意的流量劫持等问题,甚至造成个人隐私泄露(比如银行卡卡号和密码泄露)等严重的安全问题。
可以把http通信比喻成寄送信件一样,A给B寄信,信件在寄送过程中,会经过很多的邮递员之手,他们可以拆开信读取里面的内容(因为http是明文传输的)。A的信件里面的任何内容(包括各类账号和密码)都会被轻易窃取。除此之外,邮递员们还可以伪造或者修改信件的内容,导致B接收到的信件内容是假的。
比如常见的,在http通信过程中,“中间人”将广告链接嵌入到服务器发给用户的http报文里,导致用户界面出现很多不良链接; 或者是修改用户的请求头URL,导致用户的请求被劫持到另外一个网站,用户的请求永远到不了真正的服务器。这些都会导致用户得不到正确的服务,甚至是损失惨重。 https协议与http协议最主要的区别便在于加入了SSL层。此外,https协议主要采用了非对称加密、对称加密、数字证书、数字签名等要素来保障安全。 网络协议层对比

在https协议中引入了非对称加解密这一概念。在非对称加解密算法里,公钥加密的数据,有且只有唯一的私钥才能够解密,所以服务器只要把公钥发给客户端,客户端就可以用这个公钥来加密进行数据传输的对称密钥。客户端利用公钥将对称密钥发给服务器时,即使中间人截取了信息,也无法解密,因为私钥只部署在服务器,其他任何人都没有私钥,因此,只有服务器才能够解密。服务器拿到客户端的信息并用私钥解密之后,就可以拿到加解密数据用的对称密钥,通过这个对称密钥来进行后续通信的数据加解密。除此之外,非对称加密可以很好的管理对称密钥,保证每次数据加密的对称密钥都是不相同的,这样子的话,即使客户端病毒拉取到通信缓存信息,也无法窃取正常通信内容。
其中对称加密是指:加密和解密使用相同密钥的算法。它要求发送方和接收方在安全通信之前,商定一个对称密钥。对称算法的安全性完全依赖于密钥,密钥泄漏就意味着任何人都可以对他们发送或接收的消息解密,所以密钥的保密性对通信至关重要。
而数字证书则是第三方机构(CA),给网站的唯一身份证明,就像身份证,该证书包含两个主要部分,一是明文信息(包含服务器的公钥,和服务器本身的信息,及第三方机构的信息。用于传递服务器公钥,和生成消息摘要,验证信息是否被篡改),二是数字签名。
数字签名的生成过程为:将服务器网址的相关信息,先使用hash算法生成消息摘要,然后将消息摘要使用CA的私钥加密。(注意,ca的私钥,服务器是不知道的,它只有数字签名)
浏览器在收到证书之后,首先使用ca的公钥解密数字签名,生成相应的消息摘要;同时使用相同的hash算法,处理服务器网址,生成消息摘要。将两份消息摘要进行对比,完全相同即可验证服务器的公钥的未被篡改。

https整体流程如下图所示: https建立链接流程

*参考与来源文章:
blog.csdn.net/xifeijian/a…
www.cnblogs.com/whalesea/p/… blog.csdn.net/howgod/arti…

https与http共存的场景有如:

  1. app已经发布出去,其调用接口的地址为http的,那么这是必须兼容的。
  2. app中嵌入了h5页面,而这页面在以前的设计中是使用http访问的,如果换成https地址,极有可能将导致h5页面无法打开。
  3. 对于流量推广一类的业务,可能原有的http推广地址已经发送给第三方,而且即使你通知到第三方要求改为https,也不排除有http地址的访问。

针对以上场景,我们肯定是要https与http共存的。

  改https初看起来,其实就是一个域名指向的问题,也许我们只要将http的请求,直接跳转到https地址去,那么也就完成了https的切换。实际并不是这么简单的。
因为https地址中,如果加载了http资源,浏览器将认为这是不安全的资源*[1]*,将会默认阻止,这就会给你带来资源不全的问题了,比如:图片显示不了,样式加载不了,JS加载不了。因为样式类,基本上都是写在本地的,所以一般还可以,但是一些公共的js文件,往往就是存在于cdn或者其他服务器上,这时候,如果访问不了,可能就导致了业务就完全操作不了。比如:jquery效法加载失败,可能所有的操作、请求都将无效了。 如项目中的js文件无法加载,直接导致项目实效(使用$都报错)。如下图所示:

image

  将http请求直接跳转至https请求,是一种解决办法,而且很多公司都是这么干的,比如百度什么的,但是前提是,所有的服务都已切换https完成。

*来源:blog.csdn.net/ganquanzhon…
作者:ForFuture Group

如何解决问题

  1. 最笨的方法,直接复制原有代码,写成两套代码,一套为http使用,一套为https使用,http和https各自指向各自服务。

  2. 可用的方法,用同一套代码,在后台请求标识好协议,将该变量传到html页面中,进行协议替换,如:后台变量,$protocol = 'https://'; 前台接收变量 src='{$protocol}res.aa.com/jquery.js'

  3. h5方法,使用js自己加载协议情况,如在body οnlοad='aa()', 在aa() 方法中,将资源按照需求加载进来即可。

  4. 推荐方法,不指定具体协议,使用资源协议自适配,比如,当前为https页面,那么就是https资源,如果是http页面,那么就是http资源。具体方法实现简单:<script src='//cdn.bootcss.com/jquery/3.3.1/jquery.min.js'></script>

内容拓展:Mixed Content

HTTPS 网页中加载的 HTTP 资源被称之为 Mixed Content(混合内容),不同浏览器对 Mixed Content 有不一样的处理规则。

HTTPS页面里动态的引入HTTP资源,比如引入一个js文件,会被直接block掉的.在HTTPS页面里通过AJAX的方式请求HTTP资源,也会被直接block掉的。

image

 解决:

页面的head中加入:<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

意思是自动将http的不安全请求升级为https请求。

upgrade-insecure-requests详细介绍

  历史悠久的大站在往 HTTPS 迁移的过程中,工作量往往非常巨大,尤其是将所有资源都替换为 HTTPS 这一步,很容易产生疏漏。即使所有代码都确认没有问题,很可能某些从数据库读取的字段中还存在 HTTP 链接。

而通过 upgrade-insecure-requests 这个 CSP 指令,可以让浏览器帮忙做这个转换。启用这个策略后,有两个变化:

  • 页面所有 HTTP 资源,会被替换为 HTTPS 地址再发起请求;

  • 页面所有站内链接,点击后会被替换为 HTTPS 地址再跳转;

需要注意的是 upgrade-insecure-requests 只替换协议部分,所以只适用于 HTTP/HTTPS 域名和路径完全一致的场景。

*来源:blog.csdn.net/ganquanzhon…
作者:ForFuture Group

补充资料:

[1]并非所有的浏览器都停止加载了http资源,需要特别指出的是,文中的浏览器主要指的Google的Chrome浏览器。

根据 Google 的说法,Chrome 用户现在在所有主要平台上的 HTTPS 上花费了 90% 以上的浏览时间。但是,那些安全页面加载不安全的 HTTP 子资源却是很常见的。这些子资源中的许多默认情况下都是被阻止的,但有些会作为图像、音频和视频或“混合内容”潜入,混合内容可能会使用户面临风险,比如脚本、iframe 与媒体文件。
从2019 年 12 月开始测试的 Chrome 79 开始,Chrome 将会逐步阻止所有混合内容。到 2020 年 1 月,Chrome 80 会将所有混合音频和视频资源自动升级为 HTTPS,如果无法通过 HTTPS 加载,则将自动被阻止。最终,在 2020 年 2 月,Chrome 81 将所有混合图像、音频与视频自动升级为 HTTPS,并且阻止那些无法通过 HTTPS 加载的图像。
同时,Chrome 79 中还将添加一个新设置项,用户可以用来取消阻止特定站点上的混合内容。 这样的过渡使开发人员有时间将其混合内容迁移到 HTTPS 上。
类似的措施,此前我们报导过,谷歌 Chrome 工程师 Emily Stark 已经在 W3C 邮件列表上提出,计划在 HTTPS 网站上默认禁止一些通过 HTTP 下载的行为,当涉及到下载 EXE、DMG(Mac 应用二进制文件)、CRX(Chrome 扩展包) 与诸如 ZIP、GZIP、BZIP、TAR、RAR 和 7Z 等主流压缩/打包文件时,浏览器将阻止下载。默认阻止下载的这些文件类型被认为是“高风险”的,因为它们最有可能被滥用来隐藏恶意程序。

来源:www.ithome.com/0/448/673.h…

作者原文地址