淺析https引入http資源、什么是混合內容、報錯已阻止載入混合活動內容的問題及解決


  問題背景:我們在使用 https 網站時,經常會看到這樣的報錯提示:

Mixed Content: The page at 'https://' was loaded over HTTPS, but requested an insecure frame 'http://'. This request has been blocked; the content must be served over HTTPS.

一、問題原因

1、什么是混合內容?

  根據 Google 的說法,當網站上的 HTML 通過安全的 HTTPS 連接加載時會出現混合內容。Mixed Content 就是混合內容的意思

  因為網站是通過 https 安全加載的,但其他內容(例如圖像、視頻內容、樣式表和腳本)繼續通過不安全的 HTTP 加載聯系。這會導致某些 Web 內容加載安全,而某些 Web 內容加載不安全。因此得名“混合內容”。

  混合或不安全內容的問題在於,無論內容本身是否安全,它們都通過安全的 HTTPS 連接加載。當這種情況發生時,現代瀏覽器(例如 Google Chrome)會向嘗試查看網站包含不安全內容的 Web 內容的用戶顯示警告。

2、通過 HTTPS 連接加載的安全網站具有以下優勢

(1)驗證。向您的網站訪問者保證,當他們登陸您的網站並與您的網站內容互動時,他們是安全的。此外,驗證站點訪問者是否在他們想要訪問的網站上並且沒有被重定向到惡意站點。

(2)數據的完整性。直觀地告訴網站訪問者,無論他們在您的網站上采取什么行動,他們的個人和財務信息都是安全的,不會受到黑客攻擊。此外,讓瀏覽器能夠檢測黑客是否更改了瀏覽器接收的任何數據。換句話說,幫助用戶相信黑客沒有將通過您的在線商店支付的錢重定向到另一個帳戶。

(3)匿名。向網站訪問者保證他們在您網站上的行為不會被其他人攔截和惡意使用。

二、解決方案

  盡管連接安全,但在您的網站上安裝 SSL 證書並繼續收到混合內容警告可能會令人沮喪。這就是為什么有時需要采取一些額外措施來保護您的網站並保護您的網站訪問者的原因。

1、加載網頁時始終使用 HTTPS URL

  盡可能將 HTTPS 連接 (https://) 應用於網站上的所有網頁,這一點很重要

2、使用 Content-Security-Policy-Report-Only 標頭

  如果您想自動收集網站上混合內容的報告,您可以考慮將此代碼段添加到您網站的HTTP 響應標頭中:

Content-Security-Policy-Report-Only: default-src https: 'unsafe-inline' 'unsafe-eval'; report-uri https://example.com/reportingEndpoint

  盡管在混合內容成為問題之前修復它並不是 100% 可靠,但它確實可以幫助那些擁有大型網站的人掌握不安全的內容。當站點訪問者登陸包含混合內容的網頁時,會向 https://example.com/reportingEndpoint 發送報告,提醒您某些內容違反了內容安全策略。

3、使用 Upgrade-Insecure-Requests CSP 指令

  在 HTTPS 站點上自動檢測和修復混合內容警告成為問題之前的另一種方法是使用upgrade-insecure-requests指令工具。此工具會告訴瀏覽器在發出任何用戶請求之前升級所有不安全的 URL。換句話說,在為您網站前端的網站訪問者加載之前,將確保不安全的 URL 是安全的。

  為此,請將此元標記代碼片段添加到文檔的 HTML 部分:

<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

  請記住,如果通過 HTTPS 連接通過 HTTP 加載的資源在 HTTPS 上不可用,則此工具將不起作用。因此,資源不會升級為安全,也不會為站點訪問者加載。雖然這意味着網站訪問者會錯過您網站的某些內容,但這也意味着他們在瀏覽您的網站時仍能保持安全。

三、工作踩坑系列——https訪問遇到“已阻止載入混合活動內容”

  上面這篇文章可以看下,記錄一下筆記。

1、問題是什么呢?

  前端發起了一個https的Ajax請求,后端返回狀態碼為302,location為http://開頭網址,這樣就造成了混合訪問。本應該有Ajax自動處理的302跳轉就這樣被瀏覽器禁止了

2、為什么經過后端跳轉后Location由https變為了http?

  我們后端采用Java開發,部署與Tomcat,對於Servlet來說一般采用HttpServletResponse.sendRedirect(String url) 方法實現頁面跳轉(302跳轉)。那么問題是不是出在這個方法呢?答案是否定的。

  sendRedirect(String url)方法中url參數可以傳入絕對地址和相對地址。我們使用的時候一般傳入相對地址,這樣由方法內部自動轉換為絕對地址也就是返回給瀏覽器中Location參數中的地址,sendRedirect()方法內部會根據當前訪問的scheme來決定拼接后絕對地址的scheme,也就是說如果訪問地址是https開頭那么跳轉鏈接的絕對地址也會是https的,http同理。在本次實例中我們傳入的就是相對地址,跳轉鏈接的絕對路徑地址開頭是由請求地址決定的,也就是后端程序收到的HttpServletRequest請求協議一定是http開頭的。

  我們看到(圖二)中地址請求地址是由https開頭的,為什么到了后端程序后就成為了http請求呢?我們接着往下說。

  為了方便說明我畫了一張https配置的架構圖,我們使用Nginx作為反向代理服務器,上游服務器使用Tomcat,我們在Nginx層進行Https配置,由Nginx負責處理Https請求。但是Nginx自身處理方式規定向上游服務器發送請求的時候是以http的方式請求的。這也就說明了為什么我們后端代碼收到的請求是http協議,真想終於大白了。

3、解決方案:

(1)改代碼方式就不看了

(2)在1.0版本中我們的關注點都是Nginx上游服務中運行的后端代碼,我們通過對代碼的改造達到我們的目的。現在我們轉換一下思路,將關注點放在Nginx上,既然是Nginx代理之后,我們的scheme丟失,那么Nginx有沒有給我們提供一種機制保留代理之后的scheme呢,答案是肯定的。

location / { proxy_set_header X-Forwarded-Proto $scheme; }

  一行簡單的配置,就解決了我們的問題,Nginx在代理的時候保留了scheme,這樣我們在跳轉的時候可以直接使用HttpServletResponse.sendRedirect()方法


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM