🚫 為什麼我的網頁嵌入別的網站時會顯示「此頁無法連線」?完整解釋與解決方法

 

💡 前言:看似正常的網址,為什麼放進網頁卻打不開?

有許多開發者或網站編輯在做內嵌頁面(iframe)時,常常遇到這樣的情況:

我明明可以直接打開這個網址,但只要放進自己網站的 <iframe>,畫面就變成一片灰,甚至出現「此網頁無法連線」!


這並不是你的程式錯,也不是網路壞掉,而是──
對方網站的安全設定在「阻止被別人嵌入」。


🧩 情境舉例:我只是想在公司系統顯示報表

假設你正在做一個公司內部的儀表板系統,程式長這樣:

<iframe src="https://report.example.com/dashboard.html"></iframe>

你希望在畫面中直接看到「銷售報表」,但執行後卻只看到:

🖥️「此網頁無法顯示」
🔴 Console 中出現錯誤:

Refused to frame 'https://report.example.com/' because an ancestor violates the following Content Security Policy directive: "frame-ancestors 'self'"

這句話的意思是:

報表網站明確設定,只允許「自己」顯示自己,不允許被別的網站嵌入。


🔐 技術解析:這是 Content-Security-Policy 與 X-Frame-Options 的保護機制

每一個網站伺服器都可以在回應的 HTTP 標頭中加入安全設定,常見的兩種是:

1️⃣ X-Frame-Options

這個設定是舊版本的安全機制,常見三種值:

設定值 意義
DENY 不允許任何 iframe 嵌入
SAMEORIGIN 只允許相同網域的網頁嵌入
ALLOW-FROM https://example.com 僅允許指定網域嵌入

2️⃣ Content-Security-Policy: frame-ancestors

這是新版的設定,用來取代前者。
例如:

Content-Security-Policy: frame-ancestors 'self' https://main.example.com;

意思是:「只允許自己或 main.example.com 這個網站嵌入。」


🚧 為什麼企業網站常常擋住 iframe?

企業系統(如 ERP、BI、報表平台)常會設定這樣的安全機制,以避免:

  • 被惡意網站嵌入進行「點擊劫持(clickjacking)」攻擊;

  • 敏感資訊被其他頁面偷偷嵌入;

  • 不同子網域之間的資料外洩。

換句話說,這是一種「網站防護罩」。


✅ 解決方式(工程師版 × 非工程師版)

💡 方法一:在新分頁開啟(最簡單)

對一般使用者來說,只要在系統裡提供「以新分頁開啟」按鈕即可。

window.open('https://report.example.com/dashboard.html', '_blank');

✅ 優點:不需更改任何伺服器設定。
❌ 缺點:無法在同一畫面內嵌報表。


💡 方法二:請網站管理員「開白名單」

如果你有內部 IT 團隊,可以請他們在報表網站的伺服器設定中加入允許網域,例如:

Content-Security-Policy: frame-ancestors 'self' https://yourapp.example.com;

或在 Nginx / IIS / Apache 中設定:

add_header Content-Security-Policy "frame-ancestors 'self' https://yourapp.example.com";

✅ 優點:完全解決 iframe 無法顯示問題。
❌ 缺點:需要伺服器權限或內部安全審核。


💡 方法三:使用「反向代理」(進階做法)

如果你能修改後端,可建立一個 proxy endpoint,讓你的網站透過伺服器轉發請求:

app.get('/proxy/report', async (req, res) => { const response = await fetch('https://report.example.com/dashboard.html'); const html = await response.text(); res.send(html); });

然後前端嵌入:

<iframe src="/proxy/report"></iframe>

✅ 優點:繞過 CSP 限制。
❌ 缺點:需要後端支援,並可能違反公司資訊安全政策。


💡 方法四:統一部署在同一網域

若能把前端與報表都放在相同網域下,例如:

https://main.example.com/vueapp/ https://main.example.com/reports/

那就不會有「跨網域」問題,因為 CSP 的 'self' 規則允許這種情況。


🧠 延伸小知識:為什麼以前可以、現在不行?

可能是:

  1. 新網址(例如報表測試機)沒有被加進安全白名單;

  2. 伺服器版本更新後,預設啟用了更嚴格的 CSP;

  3. 或是你從 HTTP 換成 HTTPS、或反之,導致安全規則失效。


📋 總結表

問題原因 現象 解法
被 CSP 限制 iframe 顯示「無法連線」 開白名單 / 改同網域
被 X-Frame-Options 限制 Console 顯示 DENY / SAMEORIGIN 修改伺服器設定
網址載入太慢 載入後顯示 fallback 延長載入時間
混合內容(HTTP vs HTTPS) 頁面空白 改為 HTTPS
驗證頁面被擋 iframe 跳轉登入頁 改用新分頁開啟

💬 結語:有時候不是「壞掉」,而是「太安全」

當我們看到「無法連線」這種錯誤,其實是伺服器在保護自己。
理解 CSP 和 X-Frame-Options 的運作原理,就能清楚知道該改哪裡,而不是亂猜。

如果你只是要顯示外部資料而不是整個網站,也可以改成用 API 方式取資料再自己渲染,安全又彈性。


🏷️ 關鍵字建議(SEO Friendly)

iframe 無法顯示X-Frame-Options SAMEORIGINContent-Security-Policy frame-ancestorsVue iframe 報表網站安全設定CSP 錯誤解決iframe 新分頁開啟跨網域嵌入失敗

留言

這個網誌中的熱門文章

🔍Vue.js 專案錯誤排查:解決 numericFields is not defined 與合併儲存格邏輯最佳化

🔎EF Core 連 Oracle 出現 ORA-00600 [kpp_concatq:2] 的完整排錯指南(含 EF Core ToString/CultureInfo 錯誤)

🛠【ASP.NET Core + Oracle】解決 ORA-00904 "FALSE": 無效的 ID 錯誤與資料欄位動態插入顯示問題