Mở khoá Structured Clone cho tính năng Nhắn tin qua tiện ích của Chrome

Justin Lulejian
Justin Lulejian

Xuất bản: Ngày 13 tháng 4 năm 2026

Hoạt động giao tiếp giữa các thành phần tiện ích khác nhau (tập lệnh nền, tập lệnh nội dung, cửa sổ bật lên) thường dựa vào quá trình chuyển đổi tuần tự JSON. Mặc dù đáng tin cậy, nhưng JSON có những hạn chế.

Chúng tôi rất vui mừng thông báo rằng kể từ Chrome 148, nhà phát triển tiện ích có thể chọn sử dụng thuật toán sao chép có cấu trúc để chuyển đổi tuần tự thông báo thay vì JSON! Việc hiện đại hoá này cho phép bạn gửi các kiểu dữ liệu phức tạp hơn giữa các ngữ cảnh tiện ích mà không cần giải pháp thay thế cho việc chuyển đổi tuần tự theo cách thủ công.

Tại sao nên sử dụng tính năng sao chép có cấu trúc?

Quá trình chuyển đổi tuần tự JSON (thông qua JSON.stringify ở chế độ nền) có chức năng, nhưng đôi khi yêu cầu nhà phát triển phải thực hiện nhiều bước khi xử lý các loại JavaScript hiện đại.

Dưới đây là một ví dụ cụ thể mà bạn có thể gặp phải khi phát triển một tiện ích:

// 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);
});

Một số trường hợp khác mà JSON không thành công mà bạn có thể phải giải quyết là các đối tượng Set, BigInt, NaNInfinity, DateError.

Việc sử dụng tính năng chuyển đổi tuần tự sao chép có cấu trúc có nghĩa là giờ đây bạn có thể gửi nhiều đối tượng mà trước đây rất khó hoặc không thể truyền qua tính năng nhắn tin của tiện ích. Ví dụ: giờ đây, việc gửi một đối tượng Map sẽ diễn ra trực tiếp:

// 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
});

Hỗ trợ thêm nhiều loại

Tính năng sao chép có cấu trúc hỗ trợ nhiều các loại khác, chẳng hạn như FileBlob.

Cách chọn tham gia

Để đảm bảo khả năng tương thích ngược và ngăn chặn việc làm hỏng các tiện ích hiện có, tính năng này là chọn sử dụng. Bạn có thể bật tính năng này trên toàn cầu cho tiện ích bằng cách thêm một khoá duy nhất vào manifest.json:

{
  "name": "My Extension",
  "version": "1.0",
  "manifest_version": 3,
  "message_serialization": "structured_clone"
}

Nếu bạn bỏ qua hoặc dùng phiên bản Chrome thấp hơn 148, thì trình duyệt sẽ mặc định dùng chế độ triển khai hiện tại dựa trên JSON cho tiện ích.

Bằng cách hỗ trợ thuật toán sao chép có cấu trúc, chúng tôi đang đưa API nhắn tin của tiện ích gần hơn với khả năng của nền tảng web tiêu chuẩn (tương tự như postMessage được dùng trong Web Worker và giao tiếp iframe), giúp bạn linh hoạt và mạnh mẽ hơn.

Khả năng tương tác và các điểm cần lưu ý

Mặc dù chế độ triển khai chuyển đổi tuần tự bản sao có cấu trúc của chúng tôi hỗ trợ nhiều loại hơn JSON, nhưng bạn nên lưu ý một số giả định về cấu trúc và sự không tương thích với chế độ triển khai.

Các loại không được hỗ trợ

Các đối tượng dùng chung như SharedArrayBufferviệc chuyển đối tượng như ArrayBuffer không được hỗ trợ trong quá trình triển khai của chúng tôi. SharedArrayBuffer sẽ không thể chuyển đổi tuần tự hoặc huỷ chuyển đổi tuần tự (tuỳ thuộc vào tình huống) và việc cố gắng gửi một đối tượng có thể chuyển nhượng như Uint8Array sẽ gửi một bản sao thay thế.

Giao tiếp giữa các tiện ích

Chúng tôi thực thi các định dạng chuyển đổi tuần tự phù hợp để đảm bảo tính toàn vẹn của dữ liệu. Các tiện ích có định dạng chuyển đổi tuần tự không khớp không thể giao tiếp trực tiếp qua runtime.sendMessage hoặc runtime.connect. Ví dụ: nếu tiện ích A sử dụng quá trình chuyển đổi tuần tự JSON và cố gắng gửi thông báo cho Tiện ích B bằng cách sử dụng bản sao có cấu trúc, thì thông báo sẽ không gửi được và cổng sẽ đóng (và ngược lại).

Thông tin liên lạc trên trang web

Các trang web sử dụng externally_connectable sẽ tự động điều chỉnh theo định dạng chuyển đổi tuần tự của tiện ích mục tiêu. Nếu tiện ích của bạn sử dụng tính năng sao chép có cấu trúc, thì các ngữ cảnh web gửi thông báo bằng API runtime sẽ tự động sử dụng tính năng sao chép có cấu trúc (và ngược lại). Điều này có nghĩa là trang web và tiện ích phải đồng bộ hoá theo định dạng tuần tự hoá dự kiến để ngăn lỗi tuần tự hoá.

Nhắn tin bằng ứng dụng gốc

Các kênh nhắn tin gốc sẽ luôn buộc tuần tự hoá JSON. Việc cố gắng gửi các loại chỉ có thể sao chép có cấu trúc (chẳng hạn như BigInt) đến một máy chủ gốc sẽ không thành công trước khi một thông báo rời khỏi bối cảnh của tiện ích.

Phương thức toJSON()

Nếu bạn sử dụng các lớp hoặc đối tượng có phương thức toJSON() tuỳ chỉnh để thực hiện quá trình chuyển đổi tuần tự tuỳ chỉnh (ví dụ: làm sạch dữ liệu bằng cách xoá mật khẩu trước khi gửi một đối tượng), hãy lưu ý rằng phương thức sao chép có cấu trúc sẽ bỏ qua toJSON(). Thao tác này sẽ sao chép trực tiếp các giá trị thuộc tính. Nếu bạn dựa vào toJSON() để thực hiện quy trình chuyển đổi tuần tự tuỳ chỉnh, thì bạn có thể phải thực hiện một số thao tác thủ công trước khi gửi. Ví dụ:

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?

Không! Chrome cam kết hỗ trợ cả hai định dạng chuyển đổi tuần tự này trong tương lai gần.

Chia sẻ ý kiến phản hồi

Chúng tôi hy vọng tính năng mới này sẽ giúp bạn phát triển tiện ích một cách mượt mà và hiệu quả hơn.

Mặc dù chúng tôi đã tạo một bộ thử nghiệm để xác thực chức năng cho quá trình triển khai bản sao có cấu trúc, nhưng nền tảng web có vô số đối tượng. Hãy dùng thử tính năng mới này và báo cáo mọi lỗi hoặc trường hợp đặc biệt mà bạn gặp phải! Ý kiến phản hồi của bạn sẽ giúp chúng tôi cải thiện việc triển khai tính năng này cho toàn thể cộng đồng.