ปลดล็อก Structured Clone สำหรับการรับส่งข้อความของส่วนขยาย Chrome

Justin Lulejian
Justin Lulejian

เผยแพร่เมื่อวันที่ 13 เมษายน 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() ที่กำหนดเองเพื่อทำการแปลงเป็นอนุกรมที่กำหนดเอง (เช่น การล้างข้อมูลโดยการนำรหัสผ่านออกก่อนส่งออบเจ็กต์) โปรดทราบว่าการโคลนที่มีโครงสร้างจะ ละเว้น 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" }

การแปลงเป็นอนุกรม JSON จะหายไปไหม

ไม่ Chrome มุ่งมั่นที่จะรองรับรูปแบบการแปลงเป็นอนุกรมทั้ง 2 รูปแบบในอนาคตอันใกล้นี้

แชร์ความคิดเห็น

เราหวังว่าความสามารถใหม่นี้จะช่วยให้การพัฒนาส่วนขยายของคุณมีเวิร์กโฟลว์ที่ราบรื่นและมีประสิทธิภาพมากขึ้น

แม้ว่าเราจะสร้างชุดทดสอบเพื่อตรวจสอบฟังก์ชันการทำงานสำหรับการติดตั้งใช้งานการโคลนที่มีโครงสร้าง แต่แพลตฟอร์มเว็บก็มีออบเจ็กต์ที่หลากหลาย ลองใช้ฟีเจอร์ใหม่นี้และ รายงาน ข้อบกพร่องหรือกรณีพิเศษที่คุณพบ ความคิดเห็นของคุณจะช่วยเราปรับปรุงการติดตั้งใช้งานสำหรับชุมชนทั้งหมด