混合內容是指 HTTPS 頁面透過明文 HTTP 載入子資源(圖片、指令碼、樣式表、字型)。瀏覽器會阻止或警告這種行為,因為安全頁面上的不安全資源會破壞整個頁面的安全性。
兩種型別的混合內容
| 型別 | 示例 | 瀏覽器行為 |
|---|---|---|
| 主動(危險) | 指令碼、iframe、XHR、CSS | 所有瀏覽器阻止 |
| 被動(顯示) | 圖片、音訊、影片 | 顯示警告 / 降級鎖頭圖示 |
主動混合內容可以修改頁面(中間人攻擊者可以注入惡意 JavaScript),因此瀏覽器完全阻止它。被動混合內容危險性較低,但仍會降級安全指示器。
如何查詢混合內容
瀏覽器 DevTools
- 在 Chrome/Firefox 中開啟你的網站
- 開啟 DevTools(F12)→ Console 標籤
- 查詢如下錯誤:
Mixed Content: The page at 'https://example.com' was loaded over HTTPS, but requested an insecure resource 'http://example.com/image.jpg'.
命令列掃描
curl -s https://yourdomain.com | grep -oP 'http://[^"'"'"'> ]+' | sort -u
常見原因和修復方法
HTML 中硬編碼的 http:// URL
<!-- Problem -->
<img src="http://example.com/logo.png">
<!-- Fix: use protocol-relative or HTTPS -->
<img src="https://example.com/logo.png">
<img src="//example.com/logo.png">
<img src="/logo.png">
最佳實踐:儘可能使用相對路徑(/images/logo.png)。
第三方資源仍在用 HTTP
<!-- Problem -->
<script src="http://cdn.example.com/library.js"></script>
<!-- Fix -->
<script src="https://cdn.example.com/library.js"></script>
如果第三方不支援 HTTPS,找一個替代提供商或自託管該資源。
資料庫內容含有硬編碼 URL
WordPress 和其他 CMS 在資料庫中儲存絕對 URL。遷移到 HTTPS 後:
-- WordPress: update URLs in posts
UPDATE wp_posts SET post_content = REPLACE(post_content, 'http://example.com', 'https://example.com');
UPDATE wp_options SET option_value = REPLACE(option_value, 'http://example.com', 'https://example.com');
或者使用 Better Search Replace 外掛。
CSS 中的 HTTP 引用
/* Problem */
background-image: url('http://example.com/bg.jpg');
/* Fix */
background-image: url('https://example.com/bg.jpg');
background-image: url('/images/bg.jpg');
Content Security Policy (CSP) — 防止未來的混合內容
新增 CSP 頭來阻止 HTTP 資源:
Nginx:
add_header Content-Security-Policy "upgrade-insecure-requests" always;
Apache:
Header always set Content-Security-Policy "upgrade-insecure-requests"
upgrade-insecure-requests 告訴瀏覽器自動將 http:// 請求升級為 https://——在你修復源 URL 期間作為安全網。
系統性修復:全站審計
對於徹底的清理,審計你的整個網站:
1. 掃描 HTTP 引用
# Scan all HTML files for http:// URLs
find /var/www/html -name '*.html' -o -name '*.php' | xargs grep -l 'http://' 2>/dev/null
# Scan CSS files
find /var/www/html -name '*.css' | xargs grep -l 'http://' 2>/dev/null
# Scan JavaScript files
find /var/www/html -name '*.js' | xargs grep -l 'http://' 2>/dev/null
2. 按類別修復 URL
| 來源 | 修復方法 |
|---|---|
| 你自己的資源 | 改為相對路徑(/images/logo.png) |
| CDN 資源 | 更新為 https://cdn.example.com/... |
| 第三方指令碼 | 更新 URL 或尋找 HTTPS 替代 |
| 內聯 CSS | 搜尋替換 http:// → https:// |
| 資料庫內容 (WordPress) | wp search-replace 'http://yourdomain.com' 'https://yourdomain.com' |
| 模板/主題檔案 | 直接編輯原始檔 |
3. 用瀏覽器 DevTools 驗證
修復後,開啟每個頁面 → DevTools(F12)→ Console 標籤。乾淨的頁面不會顯示混合內容警告。鎖頭圖示應該是實心的(沒有破損或警告三角形)。
4. 防止未來的混合內容
在 HTML <head> 中新增此 meta 標籤作為永久安全網:
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
或透過 Nginx/Apache 配置在伺服器級別設定(如上所示)。
常見引起混合內容的內容型別
| 內容型別 | 檢查位置 | 示例 |
|---|---|---|
| 圖片 | <img src="http://..."> | 上傳的圖片、頭像、Logo |
| 指令碼 | <script src="http://..."> | 分析工具、聊天元件、廣告指令碼 |
| 樣式表 | <link href="http://..."> | 外部字型、CSS 框架 |
| 字型 | @font-face { src: url("http://...") } | Google Fonts(通常沒問題)、自定義字型 |
| iframe | <iframe src="http://..."> | 嵌入影片、地圖、元件 |
| XHR/Fetch | fetch("http://...") | JavaScript 中的 API 呼叫 |
| 背景圖片 | background-image: url("http://...") | CSS 背景 |
常見問題
混合內容會影響 SEO 嗎?
不直接影響。Google 基於頁面 URL 協議抓取,而非子資源。但是,如果混合內容觸發瀏覽器警告或阻止可見內容,使用者體驗下降——這可能透過更高的跳出率間接影響排名。
可以只用 upgrade-insecure-requests 而不修復 URL 嗎?
它可以作為權宜之計,但修復源 URL 更好。CSP 頭依賴於瀏覽器支援(所有現代瀏覽器都支援,但一些舊用戶端不支援),併為每個響應增加了一個額外的頭。
我的網站有數百個硬編碼的 HTTP URL,最快的修復方法是什麼?
立即新增 upgrade-insecure-requests CSP 頭(一行伺服器配置)。然後在程式碼庫和資料庫中做全域性搜尋替換。使用 grep -r 'http://' src/ 查詢程式碼中的硬編碼 URL。