今天产品告知列表页有些图片加载不出来,让我处理一下。一开始以为是列表图片没有设置,检查发现有判断图片是否设置,还设置了默认展示的图片。之后怀疑是图片资源过期或者不存在了,拿到相关图片的 src 值访问,发现访问正常,图片可以正常显示。并且因为图片服务器没有设置防盗链服务,所以也不会因为这个原因而加载失败。

网上寻找解决方案,得到这个错误的解释是 用一个错误的域名访问了某个节点的 https 资源。其分析存在的三种情况:

  • dns 污染
  • host 设置错误
  • 官方更新了 dns,但是 dns 缓存没有被更新,导致错误解析。

提供的解决方案是清理 DNS 缓存?后续的分析也不太匹配当前遇到的情况,就没看下去。但报错的原因感觉是正确的,因为网站本身使用了 https 协议,而要加载的图片资源使用了 http 协议,但浏览器自动将协议转换成了 https。而本地 host 设置的 http 域名访问正常,加载的图片资源使用了 http 协议,浏览器未做修改。

之前浏览器处理这种 https 域名加载非 https 资源,只是在网址栏标注网站链接不安全,资源会被正常加载。什么时候改变的?不清楚,使用 360 极速和火狐访问相关页面,图片正常加载,页面被标注为不安全。所以只有 Chrome 将不安全资源自动转换为安全资源去加载。

相反的例子是,我友链里面一位 立 flag 博客 的朋友,他的头像资源也加载不出来了。Console 栏报的错是 net::ERR_TOO_MANY_REDIRECTS。他网站原来的头像链接是 https 的,猜测他的证书过期了,他就直接取消了证书的使用,并将 https 访问转发到了 http。图片资源自然无法正常加载,请求多次 https (原链接 https 被转发到 http,http 访问又被 Chrome 转换成 https)后失败报错了。将友链的地址放到 360 极速和火狐上访问,这位仁兄的头像又显示出来了。

综合上述观察,总结了一下情况。之前所有的浏览器针对 https 的网站中的请求 http 资源相对包容一些,资源会被正常加载,然后在网址栏标注当前网站链接不安全。而近期 Chrome 浏览器采取了更加严格的策略,对于 https 网站的 http 资源自动转换为 https 链接进行加载。如果资源本身不支持 https,则自动加载失败。而网站本身因为未加载 http 资源,所以链接显示为安全。

之前针对支持 http 和 https 两种协议的资源,适配式的写法是 //xx.xx/xx,省略协议,让浏览器去自动判断并加载。Chrome 的改变可以预见,不久的将来,所有的 https 网站将只能访问 https 的资源。

所以,针对目前 Chrome 浏览器的这种策略,没有其他的办法,唯一的策略就是让资源支持 https 协议。