JSON.stringify 使用時機
您觀察得非常仔細!chrome.runtime.sendMessage 的 payload(或訊息物件本身)是否需要 JSON.stringify,主要取決於您要傳遞的數據類型以及您希望如何處理它。
基本類型: String, Number, Boolean, null.物件 (Object): 只包含 JSON-ifiable 值的普通 JavaScript 物件。陣列 (Array): 只包含 JSON-ifiable 值的陣列。
Functions DOM Nodes undefined (在序列化過程中可能會被忽略或轉為 null,取決於上下文) Dates (會被轉換為 ISO 8601 字串) RegExp Error objects (直接傳遞會丟失很多資訊,最好提取 message 和 stack 作為字串) Map, Set (需要先轉換為 Array 或 Object) 包含循環引用的物件
不使用 JSON.stringify (推薦的常見情況): 當您傳遞的 payload 本身就是一個 簡單的 JavaScript 物件或陣列,且其所有屬性/元素都是 JSON-ifiable 的 時,您不需要 手動調用 JSON.stringify。Chrome 的訊息傳遞系統會 自動 為您處理序列化和反序列化。示例: // popup.js const itemData = { title: "開會", time: "2024-08-01T10:00:00Z" }; chrome.runtime.sendMessage({ type: 'ADD_ITEM', payload: itemData }); // 直接傳遞物件 // background.js chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.type === 'ADD_ITEM') { console.log(request.payload.title); // 可以直接訪問屬性 } });這是 最常見也是最方便 的做法。
使用 JSON.stringify (較少見,特定情況): 情況 A:如果您想傳遞一個已經是 JSON 字串的數據。 例如,您從某個地方獲取到的是一個 JSON 字串,並且您想原樣傳遞它,讓接收端自己去 JSON.parse。情況 B:如果您要傳遞的物件中包含一些非標準的 JSON-ifiable 類型,但您希望通過 JSON.stringify 的第二個參數 (replacer function) 或 toJSON 方法來自定義其序列化行為。 這種情況比較高級和少見。情況 C:如果您在某些特殊情況下,需要確保傳遞的就是一個純粹的字串,避免任何自動轉換。 情況 D(您之前的例子):傳遞 Error 物件時。 直接傳遞 Error 物件 (chrome.runtime.sendMessage({ type: "AUTH_ERROR", payload: error });) 通常會導致資訊丟失,因為 Error 物件本身不是標準的 JSON-ifiable 結構,其 message, stack, name 等屬性在序列化時可能不會被完整保留。 因此,對於 Error 物件,更好的做法是 手動提取其重要屬性並構建成一個普通物件,或者使用 JSON.stringify(error, Object.getOwnPropertyNames(error)) 來嘗試捕獲更多屬性並將其轉換為字串。然後在接收端 JSON.parse。// popup.js - 發送 Error } catch (error) { chrome.runtime.sendMessage({ type: "AUTH_ERROR", // 手動構建一個包含錯誤信息的普通物件 payload: { message: error.message, name: error.name, stack: error.stack // stack 可能是個很長的字串 } // 或者使用您之前的 stringify 方法 // payload: JSON.stringify(error, Object.getOwnPropertyNames(error)) }); } // background.js - 接收 Error chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.type === "AUTH_ERROR") { // 如果 popup 發送的是普通物件 console.error("Error from popup:", request.payload.message); // 如果 popup 發送的是 stringify 後的字串 // const errorDetails = JSON.parse(request.payload); // console.error("Error from popup:", errorDetails.message); } });
大多數情況下,您不需要手動對 payload 使用 JSON.stringify。 直接傳遞簡單的 JavaScript 物件或陣列,Chrome 會自動處理序列化。只有在特殊情況下,例如處理 Error 物件、自定義序列化行為、或者您明確需要傳遞一個 JSON 字串時,才需要考慮使用 JSON.stringify。 當您使用了 JSON.stringify 發送數據時,接收端通常需要使用 JSON.parse 來將其還原。
留言
張貼留言