使用 Data URL 或是 Blob URL,開新視窗

 想把所有 HTML 內容和資料通通集中在 contentscript.js 裡維護,又不想去多建立一個 popup.html 檔案,最穩定、100% 成功、且不佔用實體檔案空間的官方標準解法叫做:「使用 Data URL 或是 Blob URL,直接把 HTML 當成網址傳給後台開啟」

請為我看看並改用以下這個極致精簡的改法,保證新視窗一跳出來就有內容:

🛠️ 終極無檔案開窗法:Data URL 注入

我們可以直接把你想寫的 HTML 原始碼轉成一個網址字串(Data URL),直接讓後台去建立這個網窗。這樣前台不需要隔空抓取 window 控制權,新視窗誕生時就自帶內容!

1. 前台 contentscript.js

直接在字串裡面把 HTML 結構、CSS 樣式與你反白的短網址資料通通串好,然後透過 btoa(Base64 編碼)轉成一個虛擬網址傳給後台:


// contentscript.js 內部的全新極簡觸發函式

function showPopupInNewWindow(selectedText) {
    // 1. 這裡是你原本寫在同一個檔案裡的 HTML 內容,資料 (${selectedText}) 直接填入
    const htmlContent = `
        <!DOCTYPE html>
        <html>
        <head>
            <meta charset="UTF-8">
            <title>短網址還原工具箱</title>
            <style>
                body { font-family: sans-serif; padding: 20px; background: #f5f5f5; color: #333; }
                h3 { color: #27ae60; margin-top: 0; }
                .content-box { background: white; padding: 12px; border-radius: 6px; border: 1px solid #ddd; word-break: break-all; font-size: 14px; }
                button { background: #e74c3c; color: white; border: none; padding: 8px 16px; border-radius: 4px; cursor: pointer; }
            </style>
        </head>
        <body>
            <h3>🔍 蝦皮短網址精確還原結果</h3>
            <div class="content-box">${selectedText}</div>
            <br>
            <button onclick="window.close()">關閉視窗</button>
        </body>
        </html>
    `;

    // 2. 將 HTML 字串安全地轉換為 Base64 網址格式
    // unescape(encodeURIComponent) 是為了完美防呆,防止中文字元在轉碼時出現亂碼
    const base64Html = btoa(unescape(encodeURIComponent(htmlContent)));
    const dataUrl = `data:text/html;charset=utf-8;base64,${base64Html}`;

    // 3. 把這個自帶內容的魔術網址傳給後台
    chrome.runtime.sendMessage({
        action: "openWindowWithUrl",
        url: dataUrl
    });
}

// 測試觸發
// showPopupInNewWindow("https://shopee.tw...");

2. 後台 background.js

後台程式碼變得更單純,它不需要管什麼非同步回傳或抓取 ID,純粹當個開窗工具人,直接把前台丟過來的 dataUrl 當作普通網址打開:


// background.js 一行收工

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
    if (message.action === "openWindowWithUrl" && message.url) {
        // 直接開啟這個已經塞滿 HTML 的虛擬網址
        chrome.windows.create({
            url: message.url,
            type: "popup",
            width: 450,
            height: 320
        });
    }
});

為什麼這個做法最優、絕對不會出現空白頁?

  1. 擺脫進程監聽問題:原來的寫法是「開窗 ➔ 隔空抓取 ➔ 寫入」,這中間只要慢了 0.01 秒,瀏覽器就會漏掉控制權。現在的寫法是「內容在誕生前就打包在網址裡」,新視窗在開窗的瞬間就是帶著你的 HTML 出生的,絕對不可能出現白色空白頁

  2. 依舊維持單一檔案:完美實現你原本的期望,所有的排版、中文字、CSS 依然通通寫在同一個 contentscript.js 檔案中,不需要多建立任何外掛檔案。

  3. 完美支援中文字:程式碼中加入了 unescape(encodeURIComponent()) 防護,你寫在 HTML 裡面的「短網址還原結果」等中文字體,在新視窗中顯示時絕對不會變成怪異的亂碼。

留言

這個網誌中的熱門文章

Offscreen Canvas

外部網頁新增 Google 日曆行程(URL模板)

批次rename