Nội dung mô tả
Sử dụng API chrome.scripting
để thực thi tập lệnh trong nhiều ngữ cảnh.
Quyền
scripting
Phạm vi cung cấp
Tệp kê khai
Để sử dụng API chrome.scripting
, hãy khai báo quyền "scripting"
trong tệp kê khai cùng với quyền của máy chủ lưu trữ để các trang chèn tập lệnh vào. Dùng khoá "host_permissions"
hoặc quyền "activeTab"
để cấp quyền tạm thời từ máy chủ. Ví dụ sau sử dụng quyền ActiveTab.
{
"name": "Scripting Extension",
"manifest_version": 3,
"permissions": ["scripting", "activeTab"],
...
}
Khái niệm và cách sử dụng
Bạn có thể sử dụng API chrome.scripting
để chèn JavaScript và CSS vào các trang web. Điều này tương tự như những gì bạn có thể thực hiện với tập lệnh nội dung. Tuy nhiên, bằng cách sử dụng không gian tên chrome.scripting
, các tiện ích có thể đưa ra quyết định trong thời gian chạy.
Mục tiêu chèn
Bạn có thể sử dụng tham số target
để chỉ định một mục tiêu nhằm chèn JavaScript hoặc CSS vào.
Trường bắt buộc duy nhất là tabId
. Theo mặc định, nội dung chèn sẽ chạy trong khung chính của thẻ được chỉ định.
function getTabId() { ... }
chrome.scripting
.executeScript({
target : {tabId : getTabId()},
files : [ "script.js" ],
})
.then(() => console.log("script injected"));
Để chạy trong tất cả các khung của thẻ đã chỉ định, bạn có thể đặt boolean allFrames
thành true
.
function getTabId() { ... }
chrome.scripting
.executeScript({
target : {tabId : getTabId(), allFrames : true},
files : [ "script.js" ],
})
.then(() => console.log("script injected in all frames"));
Bạn cũng có thể chèn vào các khung cụ thể của thẻ bằng cách chỉ định các mã nhận dạng khung riêng lẻ. Để biết thêm thông tin về mã nhận dạng khung, hãy xem API chrome.webNavigation
.
function getTabId() { ... }
chrome.scripting
.executeScript({
target : {tabId : getTabId(), frameIds : [ frameId1, frameId2 ]},
files : [ "script.js" ],
})
.then(() => console.log("script injected on target frames"));
Mã được chèn
Các tiện ích có thể chỉ định mã cần chèn thông qua tệp bên ngoài hoặc biến thời gian chạy.
Files
Tệp được chỉ định dưới dạng chuỗi là đường dẫn tương ứng với thư mục gốc của tiện ích. Mã sau đây sẽ chèn tệp script.js
vào khung chính của thẻ.
function getTabId() { ... }
chrome.scripting
.executeScript({
target : {tabId : getTabId()},
files : [ "script.js" ],
})
.then(() => console.log("injected script file"));
Hàm thời gian chạy
Khi chèn JavaScript bằng scripting.executeScript()
, bạn có thể chỉ định một hàm sẽ được thực thi thay vì một tệp. Hàm này phải là một biến hàm có sẵn cho ngữ cảnh tiện ích hiện tại.
function getTabId() { ... }
function getTitle() { return document.title; }
chrome.scripting
.executeScript({
target : {tabId : getTabId()},
func : getTitle,
})
.then(() => console.log("injected a function"));
function getTabId() { ... }
function getUserColor() { ... }
function changeBackgroundColor() {
document.body.style.backgroundColor = getUserColor();
}
chrome.scripting
.executeScript({
target : {tabId : getTabId()},
func : changeBackgroundColor,
})
.then(() => console.log("injected a function"));
Bạn có thể giải quyết vấn đề này bằng cách sử dụng thuộc tính args
:
function getTabId() { ... }
function getUserColor() { ... }
function changeBackgroundColor(backgroundColor) {
document.body.style.backgroundColor = backgroundColor;
}
chrome.scripting
.executeScript({
target : {tabId : getTabId()},
func : changeBackgroundColor,
args : [ getUserColor() ],
})
.then(() => console.log("injected a function"));
Chuỗi thời gian chạy
Nếu chèn CSS trong một trang, bạn cũng có thể chỉ định một chuỗi sẽ được dùng trong thuộc tính css
. Tuỳ chọn này chỉ dành cho scripting.insertCSS()
; bạn không thể thực thi một chuỗi bằng scripting.executeScript()
.
function getTabId() { ... }
const css = "body { background-color: red; }";
chrome.scripting
.insertCSS({
target : {tabId : getTabId()},
css : css,
})
.then(() => console.log("CSS injected"));
Xử lý kết quả
Kết quả thực thi JavaScript được chuyển đến tiện ích. Mỗi khung hình sẽ có một kết quả duy nhất. Khung chính được đảm bảo là chỉ mục đầu tiên trong mảng thu được; tất cả các khung khác theo thứ tự không xác định.
function getTabId() { ... }
function getTitle() { return document.title; }
chrome.scripting
.executeScript({
target : {tabId : getTabId(), allFrames : true},
func : getTitle,
})
.then(injectionResults => {
for (const {frameId, result} of injectionResults) {
console.log(`Frame ${frameId} result:`, result);
}
});
scripting.insertCSS()
không trả về kết quả nào.
Lời hứa
Nếu giá trị kết quả của quá trình thực thi tập lệnh là một lời hứa, Chrome sẽ đợi lời hứa đó được giải quyết và trả về giá trị kết quả.
function getTabId() { ... }
async function addIframe() {
const iframe = document.createElement("iframe");
const loadComplete =
new Promise(resolve => iframe.addEventListener("load", resolve));
iframe.src = "https://example.com";
document.body.appendChild(iframe);
await loadComplete;
return iframe.contentWindow.document.title;
}
chrome.scripting
.executeScript({
target : {tabId : getTabId(), allFrames : true},
func : addIframe,
})
.then(injectionResults => {
for (const frameResult of injectionResults) {
const {frameId, result} = frameResult;
console.log(`Frame ${frameId} result:`, result);
}
});
Ví dụ
Huỷ đăng ký tất cả tập lệnh nội dung động
Đoạn mã sau chứa một hàm có thể huỷ đăng ký tất cả tập lệnh nội dung động mà tiện ích đã đăng ký trước đó.
async function unregisterAllDynamicContentScripts() {
try {
const scripts = await chrome.scripting.getRegisteredContentScripts();
const scriptIds = scripts.map(script => script.id);
return chrome.scripting.unregisterContentScripts(scriptIds);
} catch (error) {
const message = [
"An unexpected error occurred while",
"unregistering dynamic content scripts.",
].join(" ");
throw new Error(message, {cause : error});
}
}
Để dùng thử API chrome.scripting
, hãy cài đặt mẫu tập lệnh trong kho lưu trữ mẫu tiện ích của Chrome.
Loại
ContentScriptFilter
Thuộc tính
-
ids
string[] không bắt buộc
Nếu được chỉ định,
getRegisteredContentScripts
sẽ chỉ trả về các tập lệnh có mã nhận dạng được chỉ định trong danh sách này.
CSSInjection
Thuộc tính
-
css
chuỗi không bắt buộc
Một chuỗi chứa CSS cần chèn. Phải chỉ định chính xác một trong số
files
vàcss
. -
tệp
string[] không bắt buộc
Đường dẫn của các tệp CSS cần chèn, tương ứng với thư mục gốc của tiện ích. Phải chỉ định chính xác một trong số
files
vàcss
. -
nguồn gốc
StyleOrigin không bắt buộc
Nguồn gốc kiểu của thao tác chèn. Giá trị mặc định là
'AUTHOR'
. -
mục tiêu
Chi tiết chỉ định mục tiêu để chèn CSS vào.
ExecutionWorld
Thế giới JavaScript để thực thi một tập lệnh.
Liệt kê
"ISOLATED"
Chỉ định thế giới riêng biệt, là môi trường thực thi dành riêng cho tiện ích này.
"MAIN"
Chỉ định thế giới chính của DOM, là môi trường thực thi được chia sẻ với JavaScript của trang lưu trữ.
InjectionResult
Thuộc tính
-
documentId
string
Chrome 106 trở lênTài liệu liên quan đến thao tác chèn.
-
frameId
number
Chrome 90 trở lênKhung liên kết với nội dung chèn.
-
kết quả
không bắt buộc bất kỳ
Kết quả của quá trình thực thi tập lệnh.
InjectionTarget
Thuộc tính
-
allFrames
boolean không bắt buộc
Liệu tập lệnh có nên chèn vào tất cả các khung trong thẻ hay không. Giá trị mặc định là false. Giá trị này không được đúng nếu bạn đã chỉ định
frameIds
. -
documentIds
string[] không bắt buộc
Chrome 106 trở lênMã của mã tài liệu cụ thể để chèn vào. Bạn không thể thiết lập thuộc tính này nếu đã đặt
frameIds
. -
frameIds
number[] không bắt buộc
Mã nhận dạng của khung cụ thể để chèn vào.
-
tabId
number
Mã của thẻ cần chèn.
RegisteredContentScript
Thuộc tính
-
allFrames
boolean không bắt buộc
Nếu bạn chỉ định giá trị true (đúng) thì khung này sẽ được chèn vào tất cả khung hình, ngay cả khi khung hình đó không phải là khung trên cùng trong thẻ. Mỗi khung được kiểm tra đ��c lập để biết các yêu cầu về URL; khung này sẽ không được chèn vào khung con nếu không đáp ứng các yêu cầu về URL. Giá trị mặc định là false, nghĩa là chỉ khung hình trên cùng được khớp.
-
css
string[] không bắt buộc
Danh sách các tệp CSS sẽ được đưa vào các trang phù hợp. Các mã này được chèn theo thứ tự xuất hiện trong mảng này, trước khi tạo hoặc hiển thị bất kỳ DOM nào trên trang.
-
excludeMatches
string[] không bắt buộc
Không bao gồm các trang mà tập lệnh nội dung này sẽ được chèn vào. Xem Mẫu so khớp để biết thêm chi tiết về cú pháp của các chuỗi này.
-
id
string
Mã của tập lệnh nội dung, được chỉ định trong lệnh gọi API. Không được bắt đầu bằng '_' vì tên này được dành riêng làm tiền tố cho các mã tập lệnh được tạo.
-
js
string[] không bắt buộc
Danh sách các tệp JavaScript được đưa vào các trang phù hợp. Các mã này được chèn theo thứ tự xuất hiện trong mảng này.
-
matchOriginAsFallback
boolean không bắt buộc
Chrome 119 trở lênCho biết liệu tập lệnh có thể được chèn vào khung mà URL chứa lược đồ không được hỗ trợ hay không; cụ thể là: about:, data:, blob: hoặc filesystem:. Trong những trường hợp này, nguồn gốc của URL sẽ được kiểm tra để xác định xem có nên chèn tập lệnh hay không. Nếu nguồn gốc là
null
(như trường hợp của dữ liệu: URL), thì nguồn gốc được sử dụng sẽ là khung tạo ra khung hiện tại hoặc khung đã bắt đầu quá trình điều hướng đến khung này. Lưu ý rằng đây có thể không phải là khung mẹ. -
khớp với
string[] không bắt buộc
Chỉ định những trang mà tập lệnh nội dung này sẽ được chèn vào. Xem Mẫu so khớp để biết thêm chi tiết về cú pháp của các chuỗi này. Phải được chỉ định cho
registerContentScripts
. -
persistAcrossSessions
boolean không bắt buộc
Chỉ định xem tập lệnh nội dung này có tiếp tục xuất hiện trong các phiên trong tương lai hay không. Giá trị mặc định là "true".
-
runAt
RunAt không bắt buộc
Chỉ định thời điểm các tệp JavaScript được đưa vào trang web. Giá trị ưu tiên và mặc định là
document_idle
. -
thế giới
ExecutionWorld không bắt buộc
Chrome 102 trở lên"Thế giới" JavaScript để chạy tập lệnh. Giá trị mặc định là
ISOLATED
.
ScriptInjection
Thuộc tính
-
args
bất kỳ[] không bắt buộc
Chrome 92 trở lênCác đối số cần truyền đến hàm đã cho. Giá trị này chỉ hợp lệ nếu tham số
func
được chỉ định. Các đối số này phải chuyển đổi tuần tự JSON. -
tệp
string[] không bắt buộc
Đường dẫn của các tệp JS hoặc CSS cần chèn, so với thư mục gốc của tiện ích. Phải chỉ định chính xác một trong số
files
hoặcfunc
. -
injectImmediately
boolean không bắt buộc
Chrome 102 trở lênLiệu trình chèn có cần được kích hoạt trong mục tiêu càng sớm càng tốt hay không. Lưu ý rằng điều này không đảm bảo rằng việc chèn sẽ xảy ra trước khi tải trang, vì trang có thể đã được tải vào thời điểm tập lệnh tiếp cận mục tiêu.
-
mục tiêu
Chi tiết chỉ định mục tiêu để chèn tập lệnh.
-
thế giới
ExecutionWorld không bắt buộc
Chrome 95 trở lên"Thế giới" JavaScript để chạy tập lệnh. Giá trị mặc định là
ISOLATED
. -
func
khoảng trống không bắt buộc
Chrome 92 trở lênHàm JavaScript để chèn. Hàm này sẽ được chuyển đổi tuần tự, sau đó giải tuần tự để chèn. Điều này có nghĩa là mọi tham số ràng buộc và ngữ cảnh thực thi đều sẽ bị mất. Phải chỉ định chính xác một trong số
files
hoặcfunc
.Hàm
func
sẽ có dạng như sau:() => {...}
StyleOrigin
Nguồn gốc của việc thay đổi kiểu. Xem nguồn gốc kiểu để biết thêm thông tin.
Liệt kê
"AUTHOR"
Phương thức
executeScript()
chrome.scripting.executeScript(
injection: ScriptInjection,
callback?: function,
)
Chèn một tập lệnh vào ngữ cảnh mục tiêu. Theo mặc định, tập lệnh sẽ chạy tại document_idle
hoặc chạy ngay lập tức nếu trang đã tải xong. Nếu bạn đặt thuộc tính injectImmediately
, tập lệnh sẽ chèn mà không cần chờ, ngay cả khi trang chưa tải xong. Nếu tập lệnh đánh giá là một lời hứa, trình duyệt sẽ đợi lời hứa đó được xử lý và trả về giá trị kết quả.
Tham số
-
chèn
Chi tiết về tập lệnh cần chèn.
-
số gọi lại
hàm không bắt buộc
Tham số
callback
sẽ có dạng như sau:(results: InjectionResult[]) => void
-
kết quả
-
Giá trị trả về
-
Promise<InjectionResult[]>
Chrome 90 trở lênLời hứa được hỗ trợ trong Manifest V3 trở lên nhưng lệnh gọi lại được cung cấp để có khả năng tương thích ngược. Bạn không thể sử dụng cả hai trong cùng một lệnh gọi hàm. Lời hứa sẽ được phân giải bằng cùng một loại được truyền đến lệnh gọi lại.
getRegisteredContentScripts()
chrome.scripting.getRegisteredContentScripts(
filter?: ContentScriptFilter,
callback?: function,
)
Trả về tất cả tập lệnh nội dung được đăng ký động cho tiện ích này khớp với bộ lọc nhất định.
Tham số
-
filter
ContentScriptFilter không bắt buộc
Một đối tượng để lọc các tập lệnh đã đăng ký động của phần mở rộng.
-
số gọi lại
hàm không bắt buộc
Tham số
callback
sẽ có dạng như sau:(scripts: RegisteredContentScript[]) => void
-
các tập lệnh
-
Giá trị trả về
-
Promise<RegisteredContentScript[]>
Lời hứa được hỗ trợ trong Manifest V3 trở lên nhưng lệnh gọi lại được cung cấp để có khả năng tương thích ngược. Bạn không thể sử dụng cả hai trong cùng một lệnh gọi hàm. Lời hứa sẽ được phân giải bằng cùng một loại được truyền đến lệnh gọi lại.
insertCSS()
chrome.scripting.insertCSS(
injection: CSSInjection,
callback?: function,
)
Chèn biểu định kiểu CSS vào ngữ cảnh đích. Nếu bạn chỉ định nhiều khung, hệ thống sẽ bỏ qua các lượt chèn không thành công.
Tham số
-
chèn
Thông tin chi tiết về kiểu cần chèn.
-
số gọi lại
hàm không bắt buộc
Tham số
callback
sẽ có dạng như sau:() => void
Giá trị trả về
-
Promise<void>
Chrome 90 trở lênLời hứa được hỗ trợ trong Manifest V3 trở lên nhưng lệnh gọi lại được cung cấp để có khả năng tương thích ngược. Bạn không thể sử dụng cả hai trong cùng một lệnh gọi hàm. Lời hứa sẽ được phân giải bằng cùng một loại được truyền đến lệnh gọi lại.
registerContentScripts()
chrome.scripting.registerContentScripts(
scripts: RegisteredContentScript[],
callback?: function,
)
Đăng ký một hoặc nhiều tập lệnh nội dung cho tiện ích này.
Tham số
-
các tập lệnh
Chứa danh sách các tập lệnh cần đăng ký. Nếu xảy ra lỗi trong quá trình phân tích cú pháp tập lệnh/xác thực tệp hoặc nếu các mã nhận dạng được chỉ định đã tồn tại, thì không có tập lệnh nào được đăng ký.
-
số gọi lại
hàm không bắt buộc
Tham số
callback
sẽ có dạng như sau:() => void
Giá trị trả về
-
Promise<void>
Lời hứa được hỗ trợ trong Manifest V3 trở lên nhưng lệnh gọi lại được cung cấp để có khả năng tương thích ngược. Bạn không thể sử dụng cả hai trong cùng một lệnh gọi hàm. Lời hứa sẽ được phân giải bằng cùng một loại được truyền đến lệnh gọi lại.
removeCSS()
chrome.scripting.removeCSS(
injection: CSSInjection,
callback?: function,
)
Xoá biểu định kiểu CSS mà tiện ích này đã chèn trước đó khỏi ngữ cảnh đích.
Tham số
-
chèn
Chi tiết về các kiểu cần xoá. Xin lưu ý rằng các thuộc tính
css
,files
vàorigin
phải khớp chính xác với biểu định kiểu được chèn thông quainsertCSS
. Bạn không thể xoá biểu định kiểu không tồn tại. -
số gọi lại
hàm không bắt buộc
Tham số
callback
sẽ có dạng như sau:() => void
Giá trị trả về
-
Promise<void>
Lời hứa được hỗ trợ trong Manifest V3 trở lên nhưng lệnh gọi lại được cung cấp để có khả năng tương thích ngược. Bạn không thể sử dụng cả hai trong cùng một lệnh gọi hàm. Lời hứa sẽ được phân giải bằng cùng một loại được truyền đến lệnh gọi lại.
unregisterContentScripts()
chrome.scripting.unregisterContentScripts(
filter?: ContentScriptFilter,
callback?: function,
)
Huỷ đăng ký tập lệnh nội dung cho tiện ích này.
Tham số
-
filter
ContentScriptFilter không bắt buộc
Nếu được chỉ định, chỉ huỷ đăng ký tập lệnh nội dung động khớp với bộ lọc. Nếu không, tất cả tập lệnh nội dung động của tiện ích sẽ bị huỷ đăng ký.
-
số gọi lại
hàm không bắt buộc
Tham số
callback
sẽ có dạng như sau:() => void
Giá trị trả về
-
Promise<void>
Lời hứa được hỗ trợ trong Manifest V3 trở lên nhưng lệnh gọi lại được cung cấp để có khả năng tương thích ngược. Bạn không thể sử dụng cả hai trong cùng một lệnh gọi hàm. Lời hứa sẽ được phân giải bằng cùng một loại được truyền đến lệnh gọi lại.
updateContentScripts()
chrome.scripting.updateContentScripts(
scripts: RegisteredContentScript[],
callback?: function,
)
Cập nhật một hoặc nhiều tập lệnh nội dung cho phần mở rộng này.
Tham số
-
các tập lệnh
Chứa danh sách các tập lệnh cần cập nhật. Một thuộc tính chỉ được cập nhật cho tập lệnh hiện có nếu thuộc tính đó được chỉ định trong đối tượng này. Nếu xảy ra lỗi trong quá trình phân tích cú pháp tập lệnh/xác thực tệp hoặc nếu các mã nhận dạng được chỉ định không tương ứng với tập lệnh đã đăng ký đầy đủ, thì sẽ không có tập lệnh nào được cập nhật.
-
số gọi lại
hàm không bắt buộc
Tham số
callback
sẽ có dạng như sau:() => void
Giá trị trả về
-
Promise<void>
Lời hứa được hỗ trợ trong Manifest V3 trở lên nhưng lệnh gọi lại được cung cấp để có khả năng tương thích ngược. Bạn không thể sử dụng cả hai trong cùng một lệnh gọi hàm. Lời hứa sẽ được phân giải bằng cùng một loại được truyền đến lệnh gọi lại.