Tổng quan về cấu trúc

Tiện ích là các gói được nén gồm HTML, CSS, JavaScript, hình ảnh và các tệp khác được dùng trong nền tảng web, giúp tuỳ chỉnh trải nghiệm duyệt web trên Google Chrome. Tiện ích được tạo bằng công nghệ web và có thể sử dụng cùng một API mà trình duyệt cung cấp cho web mở.

Tiện ích có nhiều khả năng chức năng. Chúng có thể sửa đổi nội dung web mà người dùng nhìn thấy và tương tác hoặc mở rộng và thay đổi hành vi của chính trình duyệt.

Hãy coi tiện ích là cửa ngõ giúp trình duyệt Chrome trở thành trình duyệt phù hợp nhất với bạn.

Tệp mở rộng

Tiện ích có nhiều loại tệp và số lượng thư mục, nhưng tất cả đều phải có một [tệp kê khai][docs-manifest]. Một số tiện ích cơ bản nhưng hữu ích có thể chỉ bao gồm tệp kê khai và biểu tượng trên thanh công cụ của tiện ích đó.

Tệp kê khai có tên manifest.json cung cấp cho trình duyệt thông tin về tiện ích, chẳng hạn như các tệp quan trọng nhất và những chức năng mà tiện ích có thể sử dụng.

{
  "name": "My Extension",
  "version": "2.1",
  "description": "Gets information from Google.",
  "icons": {
    "128": "icon_16.png",
    "128": "icon_32.png",
    "128": "icon_48.png",
    "128": "icon_128.png"
  },
  "background": {
    "persistent": false,
    "scripts": ["background_script.js"]
  },
  "permissions": ["https://*.google.com/", "activeTab"],
  "browser_action": {
    "default_icon": "icon_16.png",
    "default_popup": "popup.html"
  }
}

Tiện ích phải có một biểu tượng nằm trên thanh công cụ của trình duyệt. Các biểu tượng trên thanh công cụ giúp người dùng dễ dàng truy cập và biết được những tiện ích nào đã cài đặt. Hầu hết người dùng sẽ tương tác với một tiện ích sử dụng cửa sổ bật lên bằng cách nhấp vào biểu tượng.

Tiện ích Google Mail Checker này sử dụng một thao tác trên trình duyệt:

Ảnh chụp màn hình của tiện ích Google Mail Checker

Tiện ích Mappy này sử dụng một thao tác trên trangtập lệnh nội dung:

Ảnh chụp màn hình tiện ích Mappy

Tham chiếu đến tệp

Bạn có thể tham chiếu các tệp của tiện ích bằng cách sử dụng URL tương đối, giống như các tệp trong một trang HTML thông thường.

<img src="images/my_image.png">

Ngoài ra, bạn cũng có thể truy cập vào từng tệp bằng URL tuyệt đối.

chrome-extension://EXTENSION_ID/PATH_TO_FILE

Trong URL tuyệt đối, EXTENSION_ID là giá trị nhận dạng riêng biệt mà hệ thống tiện ích tạo cho mỗi tiện ích. Bạn có thể xem mã nhận dạng của tất cả các tiện ích đã tải bằng cách truy cập vào URL chrome://extensions. PATH_TO_FILE là vị trí của tệp trong thư mục trên cùng của tiện ích; vị trí này khớp với URL tương đối.

Mã nhận dạng tiện ích có thể thay đổi trong khi bạn đang làm việc trên một tiện ích chưa đóng gói. Cụ thể, mã nhận dạng của một tiện ích chưa đóng gói sẽ thay đổi nếu tiện ích đó được tải từ một thư mục khác; mã nhận dạng sẽ thay đổi một lần nữa khi tiện ích được đóng gói. Nếu mã của một tiện ích dựa vào một URL tuyệt đối, thì tiện ích đó có thể sử dụng phương thức chrome.runtime.getURL() để tránh mã hoá cứng mã nhận dạng trong quá trình phát triển.

Kiến trúc

Cấu trúc của một tiện ích sẽ phụ thuộc vào chức năng của tiện ích đó, nhưng nhiều tiện ích mạnh mẽ sẽ bao gồm nhiều thành phần:

Tập lệnh nền

Tập lệnh nền là trình xử lý sự kiện của tiện ích; tập lệnh này chứa các trình nghe cho những sự kiện trình duyệt quan trọng đối với tiện ích. Nó sẽ ở trạng thái không hoạt động cho đến khi một sự kiện được kích hoạt, sau đó thực hiện logic được hướng dẫn. Một tập lệnh nền hiệu quả chỉ được tải khi cần và được huỷ tải khi không hoạt động.

Phần tử trên giao diện người dùng

Giao diện người dùng của tiện ích phải có mục đích rõ ràng và tối giản. Giao diện người dùng phải tuỳ chỉnh hoặc cải thiện trải nghiệm duyệt web mà không làm người dùng mất tập trung. Hầu hết các tiện ích đều có thao tác trên trình duyệt hoặc thao tác trên trang, nhưng có thể chứa các dạng giao diện người dùng khác, chẳng hạn như trình đơn theo bối cảnh, sử dụng thanh địa chỉ hoặc tạo phím tắt.

Các trang giao diện người dùng của tiện ích, chẳng hạn như cửa sổ bật lên, có thể chứa các trang HTML thông thường có logic JavaScript. Các tiện ích cũng có thể gọi tabs.create hoặc window.open() để hiển thị các tệp HTML bổ sung có trong tiện ích.

Tiện ích sử dụng thao tác trên trang và cửa sổ bật lên có thể dùng API declarativecontent để đặt các quy tắc trong tập lệnh nền cho thời điểm cửa sổ bật lên có sẵn cho người dùng. Khi đáp ứng các điều kiện, tập lệnh nền sẽ giao tiếp với cửa sổ bật lên để người dùng có thể nhấp vào biểu tượng của cửa sổ đó.

Một cửa sổ trình duyệt chứa một thao tác trên trang hiển thị cửa sổ bật lên

Tập lệnh nội dung

Các tiện ích đọc hoặc ghi vào trang web sẽ sử dụng một tập lệnh nội dung. Tập lệnh nội dung chứa JavaScript thực thi trong bối cảnh của một trang đã được tải vào trình duyệt. Tập lệnh nội dung đọc và sửa đổi DOM của các trang web mà trình duyệt truy cập.

Cửa sổ trình duyệt có thao tác trang và tập lệnh nội dung

Tập lệnh nội dung có thể giao tiếp với tiện ích mẹ bằng cách trao đổi thông báo và lưu trữ các giá trị bằng API storage.

Cho biết đường dẫn giao tiếp giữa tập lệnh nội dung và tiện ích mẹ

Trang tuỳ chọn

Tương tự như cách tiện ích cho phép người dùng tuỳ chỉnh trình duyệt Chrome, trang lựa chọn cho phép tuỳ chỉnh tiện ích. Bạn có thể dùng các lựa chọn để bật các tính năng và cho phép người dùng chọn chức năng phù hợp với nhu cầu của họ.

Sử dụng API Chrome

Ngoài việc có quyền truy cập vào các API giống như trang web, các tiện ích cũng có thể sử dụng các API dành riêng cho tiện ích để tạo mối liên kết chặt chẽ với trình duyệt. Cả tiện ích và trang web đều có thể truy cập vào phương thức window.open() tiêu chuẩn để mở một URL, nhưng tiện ích có thể chỉ định cửa sổ mà URL đó sẽ xuất hiện bằng cách sử dụng phương thức tabs.create của API Chrome.

Phương thức không đồng bộ so với phương thức đồng bộ

Hầu hết các phương thức Chrome API đều là phương thức không đồng bộ: các phương thức này trả về ngay lập tức mà không cần chờ thao tác hoàn tất. Nếu tiện ích cần biết kết quả của một thao tác không đồng bộ, tiện ích có thể truyền một hàm callback vào phương thức. Lệnh gọi lại sẽ được thực thi sau, có thể là muộn hơn nhiều, sau khi phương thức trả về.

Nếu cần điều hướng thẻ hiện tại mà người dùng đã chọn đến một URL mới, thì tiện ích sẽ cần lấy mã nhận dạng của thẻ hiện tại, sau đó cập nhật địa chỉ của thẻ đó thành URL mới.

Nếu phương thức tabs.query là đồng bộ, thì phương thức này có thể có dạng như bên dưới.

//THIS CODE DOESN'T WORK
var tab = chrome.tabs.query({'active': true}); //WRONG!!!
chrome.tabs.update(tab.id, {url:newUrl});
someOtherFunction();

Phương pháp này sẽ không thành công vì query() là không đồng bộ. Phương thức này sẽ trả về mà không cần chờ tác vụ hoàn tất và không trả về giá trị. Một phương thức là không đồng bộ khi tham số gọi lại có trong chữ ký của phương thức đó.

// Signature for an asynchronous method
chrome.tabs.query(object queryInfo, function callback)

Để truy vấn chính xác một thẻ và cập nhật URL của thẻ đó, tiện ích phải sử dụng tham số gọi lại.

//THIS CODE WORKS
chrome.tabs.query({'active': true}, function(tabs) {
  chrome.tabs.update(tabs[0].id, {url: newUrl});
});
someOtherFunction();

Trong mã trên, các dòng được thực thi theo thứ tự sau: 1, 4, 2. Hàm callback được chỉ định cho query() sẽ được gọi rồi thực thi dòng 2, nhưng chỉ sau khi có thông tin về thẻ hiện được chọn. Điều này xảy ra vào một thời điểm nào đó sau khi query() trả về. Mặc dù update() là không đồng bộ, nhưng mã không sử dụng tham số gọi lại, vì tiện ích không làm gì với kết quả của quá trình cập nhật.

// Synchronous methods have no callback option and returns a type of string
string chrome.runtime.getURL()

Phương thức này đồng bộ trả về URL dưới dạng string và không thực hiện bất kỳ công việc không đồng bộ nào khác.

Thông tin chi tiết khác

Để biết thêm thông tin, hãy khám phá tài liệu tham khảo API của Chrome và xem video sau.

Giao tiếp giữa các trang

Các thành phần khác nhau trong một tiện ích thường cần giao tiếp với nhau. Các trang HTML khác nhau có thể tìm thấy nhau bằng cách sử dụng các phương thức chrome.extension, chẳng hạn như getViews()getBackgroundPage(). Sau khi một trang có thông tin tham chiếu đến các trang tiện ích khác, trang đầu tiên có thể gọi các hàm trên các trang khác và thao tác với DOM của các trang đó. Ngoài ra, tất cả các thành phần của tiện ích đều có thể truy cập vào các giá trị được lưu trữ bằng API storage và giao tiếp thông qua truyền thông báo.

Tiết kiệm dữ liệu và chế độ ẩn danh

Các tiện ích có thể lưu dữ liệu bằng API storage, API bộ nhớ trên web HTML5 hoặc bằng cách đưa ra các yêu cầu máy chủ dẫn đến việc lưu dữ liệu. Khi tiện ích cần lưu trữ nội dung nào đó, trước tiên, hãy xem xét liệu nội dung đó có đến từ cửa sổ ẩn danh hay không. Theo mặc định, các tiện ích không chạy trong cửa sổ ẩn danh.

Chế độ ẩn danh đảm bảo rằng cửa sổ sẽ không để lại dấu vết. Khi xử lý dữ liệu từ các cửa sổ ẩn danh, các tiện ích phải tuân thủ lời hứa này. Nếu một tiện ích thường lưu nhật ký duyệt web, thì đừng lưu nhật ký từ các cửa sổ ẩn danh. Tuy nhiên, các tiện ích có thể lưu trữ các lựa chọn ưu tiên về chế độ cài đặt từ bất kỳ cửa sổ nào, dù là cửa sổ ẩn danh hay không.

Để phát hiện xem một cửa sổ có đang ở chế độ ẩn danh hay không, hãy kiểm tra thuộc tính incognito của đối tượng tabs.Tab hoặc windows.Window có liên quan.

function saveTabData(tab) {
  if (tab.incognito) {
    return;
  } else {
    chrome.storage.local.set({data: tab.url});
  }
}

Thực hiện bước tiếp theo

Sau khi đọc thông tin tổng quan và hoàn tất hướng dẫn Bắt đầu, các nhà phát triển sẽ sẵn sàng bắt đầu viết tiện ích của riêng mình! Tìm hiểu sâu hơn về thế giới Chrome tuỳ chỉnh thông qua các tài nguyên sau.