1. 程式人生 > 實用技巧 >分析https網頁載入http資源導致的頁面報錯原因及其解決方案

分析https網頁載入http資源導致的頁面報錯原因及其解決方案

https網頁載入http資源導致的頁面報錯及解決方案

  https是當下的網站的主流趨勢,甚至像蘋果這樣的大公司,則完全要求使用者必須使用https地址。

  然而對於以前http連結來說,我們往往就存在一個相容性問題,因為你不可能一下就全部切換過去,應該在很長一段時間內,https與http將共存。

  https與http共存的場景有如:

    1. app已經發布出去,其呼叫介面的地址為http的,那麼這是必須相容的。

    2. app中嵌入了h5頁面,而這頁面在以前的設計中是使用http訪問的,如果換成https地址,極有可能將導致h5頁面無法開啟。

    3. 對於流量推廣一類的業務,可能原有的http推廣地址已經發送給第三方,而且即使你通知到第三方要求改為https,也不排除有http地址的訪問。

  針對以上場景,我們肯定是要https與http共存的。

  改https初看起來,其實就是一個域名指向的問題,也許我們只要將http的請求,直接跳轉到https地址去,那麼也就完成了https的切換。實際並不是這麼簡單的。

  因為https地址中,如果載入了http資源,瀏覽器將認為這是不安全的資源,將會預設阻止,這就會給你帶來資源不全的問題了,比如:圖片顯示不了,樣式載入不了,JS載入不了。因為樣式類,基本上都是寫在本地的,所以一般還可以,但是一些公共的js檔案,往往就是存在於cdn或者其他伺服器上,這時候,如果訪問不了,可能就導致了業務就完全操作不了。比如:jquery效法載入失敗,可能所有的操作、請求都將無效了。

如專案中的js檔案無法載入,直接導致專案實效(使用$都報錯)。如下圖所示:

  將http請求直接跳轉至https請求,是一種解決辦法,而且很多公司都是這麼幹的,比如百度什麼的,但是前提是,你所有的服務都已切換https完成。

  但是對於,要相容https、http兩種協議的情況,怎樣才能做到呢?

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掉的。

解決:

頁面的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 域名和路徑完全一致的場景。