[Chrome Extension] 在 contentScript 中注入 iframe
注意
本文的 manifest.json 範例使用 Manifest V2(MV2) 格式(包含 browser_action、background.scripts、舊版 web_accessible_resources),在 MV3 中這些欄位均已更新。iframe 注入的技術本身仍然可用,但請依照 MV3 格式更新 manifest。
在 Chrome Extension 中,為了避免樣式或其他原因造成的干擾,很常使用的一種技巧是透過 content script 在網頁中注入 iframe,而 iframe 的 src 則帶入 chrome extension 的 html 檔。

Message API Sandbox @ PJCHENder Github
實作步驟
透過下面的步驟就可以在網頁中載入 iframe
建立 contentScript
這支 contentScript 是用來在網頁上執行,而目的是要注入自己 extension 的 iframe,在 <iframe src="" /> 的地方,src 要帶入的是 extension 內的 HTML 檔,這個檔案的路徑可以透過 chrome.runtime.getURL(<檔案名稱>) 取得。
- 建立一個
div元素,並將它append在網頁內 - 建立一個
iframe元素,src的地方透過chrome.runtime.getURL(<檔案名稱>)載入 extension 內部的檔案 - 將
iframe元素透過prepend方法掛載到root元素內
// contentScript.js
console.log('Here is contentScript');
createIframe();
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
console.log('Get response in contentScript, the request is from: ', request.from);
});
// 透過下面的程式碼可以注入 iframe
function createIframe() {
// STEP 1:建立一個 `div`,並將它 `append` 在網頁內
const root = document.createElement('div');
root.id = 'root';
document.body.appendChild(root);
// STEP 2:建立一個 `iframe` 元素,`src` 的地方透過
// `chrome.runtime.getURL(<檔案名稱>)` 載入 extension 內部的檔案
const iframe = document.createElement('iframe');
iframe.id = 'iframe-in-root';
iframe.allow = 'microphone;camera;';
iframe.sandbox = 'allow-scripts allow-same-origin allow-forms';
iframe.setAttribute('allowFullScreen', '');
iframe.scrolling = 'no';
iframe.style.cssText = `
width: 50%;
height: 50%;
border: 0;
margin: 0;
z-index: 2147483647;
background-color: #EAEAEA;
border: 1px solid #EAEAEA;
filter: none;
display: block;
`;
// ⚠️ 重點:src 要帶入的連結是 chrome extension 內部的網址
iframe.src = chrome.runtime.getURL('index.html');
root.style.cssText = `
position: fixed;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
z-index: 2147483647;
`;
// STEP 3:將 iframe 元素掛載到 root 元素內
root.prepend(iframe);
}
建立 iframe 的內容
index.html
這是 iframe 中在載入的 html 檔案:
<!-- Copyright 2017 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<html>
<head>
<title>Water Popup</title>
<style>
body {
text-align: center;
}
#hydrateImage {
width: 100px;
margin: 5px;
}
button {
margin: 5px;
outline: none;
}
button:hover {
outline: #80deea dotted thick;
}
</style>
</head>
<body>
<img src="./stay_hydrated.png" id="hydrateImage" />
<button id="send-message">SendMessage</button>
<button id="send-tabs-message">SendTabsMessage</button>
<!-- ⚠️ 重點:若有需要使用 JS 可在此載入 -->
<script src="index.js"></script>
</body>
</html>