เผยแพร่: 22 เมษายน 2026
การสื่อสารระหว่างคอมโพเนนต์ส่วนขยายต่างๆ (สคริปต์พื้นหลัง สคริปต์เนื้อหา ป๊อปอัป) มักจะอาศัยการซีเรียลไลซ์ JSON แม้ว่า JSON จะเชื่อถือได้ แต่ก็มีข้อจำกัด
เรายินดีที่จะแจ้งให้ทราบว่าตั้งแต่ Chrome 148 เป็นต้นไป นักพัฒนาส่วนขยายจะเลือกใช้อัลกอริทึมการโคลนแบบมีโครงสร้าง สำหรับการซีเรียลไลซ์ข้อความแทน JSON ได้ การปรับปรุงนี้ช่วยให้คุณ ส่งประเภทข้อมูลที่ซับซ้อนมากขึ้นระหว่างบริบทของส่วนขยายได้โดยไม่ต้อง แก้ปัญหาการเรียงอันดับด้วยตนเอง
ทำไมจึงต้องใช้การโคลนที่มีโครงสร้าง
การแปลง JSON เป็นอนุกรม (ผ่าน JSON.stringify เบื้องหลัง) ใช้งานได้ แต่บางครั้งนักพัฒนาซอฟต์แวร์ต้อง ดิ้นรนเมื่อต้องจัดการกับประเภท JavaScript สมัยใหม่
ต่อไปนี้คือตัวอย่างเฉพาะที่คุณอาจพบเมื่อพัฒนาส่วนขยาย
// Sending a Map with JSON serialization
const myMap = new Map([['id', 123]]);
// Arrives as {} on the other side!
chrome.runtime.sendMessage(myMap);
// Workaround: Convert Map to an Array of entries before sending
const message = Array.from(myMap.entries());
chrome.runtime.sendMessage(message);
// On the receiving side:
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
const receivedMap = new Map(message);
});
สถานการณ์อื่นๆ ที่ JSON ล้มเหลวซึ่งคุณอาจต้องใช้การแก้ปัญหาชั่วคราว ได้แก่ ออบเจ็กต์ Set, BigInt, NaN และ Infinity, Date และ Error
การใช้การซีเรียลไลซ์การโคลนที่มีโครงสร้างหมายความว่าตอนนี้คุณสามารถส่งออบเจ็กต์ต่างๆ ที่ก่อนหน้านี้ส่งผ่านการรับส่งข้อความของส่วนขยายได้ยากหรือส่งไม่ได้
เช่น ตอนนี้การส่งออบเจ็กต์ Map จะทำได้โดยตรง
// Sending a Map with Structured Clone
const myMap = new Map([['id', 123]]);
// Arrives as a Map on the other side!
chrome.runtime.sendMessage(myMap);
// On the receiving side:
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
// message is already a Map instance!
console.log(message.get('id')); // 123
});
ประเภทที่รองรับเพิ่มเติม
การโคลนที่มีโครงสร้างรองรับประเภทอื่นๆ
มากมาย เช่น File และ Blob
วิธีเลือกเข้าร่วม
ฟีเจอร์นี้เป็นแบบเลือกใช้เพื่อให้มั่นใจว่าสามารถใช้งานร่วมกับเวอร์ชันก่อนหน้าได้และป้องกันไม่ให้ส่วนขยายที่มีอยู่ใช้งานไม่ได้ คุณเปิดใช้ฟีเจอร์นี้ทั่วโลกสำหรับส่วนขยายได้โดยเพิ่มคีย์เดียวลงใน manifest.json ดังนี้
{
"name": "My Extension",
"version": "1.0",
"manifest_version": 3,
"message_serialization": "structured_clone"
}
หากไม่มี หรือใช้ Chrome เวอร์ชันต่ำกว่า 148 เบราว์เซอร์จะใช้การติดตั้งใช้งานตาม JSON ปัจจุบันสำหรับส่วนขยายเป็นค่าเริ่มต้น
การรองรับอัลกอริทึมการโคลนที่มีโครงสร้างช่วยให้เราสามารถปรับ API การรับส่งข้อความของส่วนขยายให้สอดคล้องกับความสามารถของแพลตฟอร์มเว็บมาตรฐานได้มากขึ้น
(คล้ายกับ postMessage ที่ใช้ในการสื่อสารของ Web Worker และ iframe) ซึ่งจะช่วยให้คุณมีความยืดหยุ่นและมีประสิทธิภาพมากขึ้น
ความสามารถในการทำงานร่วมกันและข้อควรระวัง
แม้ว่าการใช้งานการซีเรียลไลซ์การโคลนที่มีโครงสร้างจะรองรับประเภทต่างๆ มากกว่า JSON แต่ก็มีข้อสันนิษฐานด้านสถาปัตยกรรมและความไม่เข้ากันกับการใช้งานที่คุณควรทราบ
ประเภทที่ไม่รองรับ
การติดตั้งใช้งานของเราไม่รองรับออบเจ็กต์ที่แชร์ เช่น
SharedArrayBuffer
และการโอน
ออบเจ็กต์
เช่น ArrayBuffer
SharedArrayBuffer จะไม่สามารถซีเรียลไลซ์หรือดีซีเรียลไลซ์ (ขึ้นอยู่กับ
สถานการณ์) และการพยายามส่งออบเจ็กต์ที่โอนได้ เช่น Uint8Array จะ
ส่งสำเนาแทน
การสื่อสารจากส่วนขยายหนึ่งไปยังอีกส่วนขยายหนึ่ง
เราบังคับใช้รูปแบบการทำให้เป็นอนุกรมที่ตรงกันเพื่อให้มั่นใจว่าข้อมูลมีความสมบูรณ์ ส่วนขยายที่มีรูปแบบการเรียงอันดับไม่ตรงกันจะสื่อสารผ่าน runtime.sendMessage หรือ runtime.connect โดยตรงไม่ได้ เช่น หากส่วนขยาย A ใช้การซีเรียลไลซ์ JSON และพยายามส่งข้อความไปยังส่วนขยาย B โดยใช้การโคลนที่มีโครงสร้าง ระบบจะไม่สามารถส่งข้อความและพอร์ตจะปิด (และในทางกลับกัน)
การสื่อสารในหน้าเว็บ
หน้าเว็บที่ใช้ externally_connectable จะปรับให้เข้ากับรูปแบบการซีเรียลไลซ์ของส่วนขยายเป้าหมายโดยอัตโนมัติ หากส่วนขยายใช้การโคลนแบบมีโครงสร้าง บริบทเว็บที่ส่งข้อความโดยใช้ runtime API จะใช้การโคลนแบบมีโครงสร้าง (และในทางกลับกัน) โดยอัตโนมัติ ซึ่งหมายความว่าเว็บไซต์และส่วนขยายต้องซิงค์กัน
ในรูปแบบการทำให้เป็นอนุกรมที่คาดไว้เพื่อป้องกันข้อผิดพลาดในการทำให้เป็นอนุกรม
การรับส่งข้อความแบบเดิม
ช่องทางการรับส่งข้อความดั้งเดิมจะยังคงบังคับให้ใช้การซีเรียลไลซ์ JSON เสมอ
การพยายามส่งประเภทที่โคลนแบบมีโครงสร้างเท่านั้น (เช่น BigInt) ไปยังโฮสต์ดั้งเดิม
จะล้มเหลวก่อนที่ข้อความจะออกจากบริบทของส่วนขยาย
เมธอด toJSON()
หากคุณใช้คลาสหรือออบเจ็กต์ที่มีtoJSON()เมธอดที่กำหนดเองเพื่อทำการซีเรียลไลเซชันที่กำหนดเอง (เช่น การล้างข้อมูลโดยการนำรหัสผ่านออกก่อนส่งออบเจ็กต์) โปรดทราบว่า Structured Clone จะไม่สนใจ toJSON() โดยจะคัดลอกค่าพร็อพเพอร์ตี้โดยตรง หากคุณใช้ toJSON() สำหรับการซีเรียลไลซ์ที่กำหนดเอง คุณอาจต้องดำเนินการบางอย่างด้วยตนเองก่อนส่ง เช่น
class User {
constructor(name, password) {
this.name = name;
this.password = password;
}
// This will be ignored by structured clone!
toJSON() {
return { name: this.name };
}
}
const user = new User("Alice", "secret123");
// JSON -> {"name":"Alice"}
// Structured Clone -> { name: "Alice", password: "secret123" }
Is JSON serialization going away?
ไม่เอาด้วยหรอก Chrome มุ่งมั่นที่จะรองรับรูปแบบการเรียงอันดับทั้ง 2 รูปแบบในอนาคตอันใกล้
แชร์ความคิดเห็น
เราหวังว่าความสามารถใหม่นี้จะช่วยให้เวิร์กโฟลว์การพัฒนาส่วนขยายของคุณราบรื่นและมีประสิทธิภาพมากขึ้น
แม้ว่าเราจะสร้างชุดทดสอบเพื่อตรวจสอบความถูกต้องของฟังก์ชันการทำงานสำหรับการติดตั้งใช้งานการโคลนที่มีโครงสร้าง แต่แพลตฟอร์มเว็บก็มีออบเจ็กต์ที่หลากหลายมาก ลองใช้ฟีเจอร์ใหม่นี้และรายงานข้อบกพร่องหรือกรณีที่พบ ความคิดเห็นของคุณจะช่วยเราปรับปรุง การใช้งานสำหรับชุมชนทั้งหมด