我不知道什么是最好的表達方式,但我決定在這里發一個帖子,因為我已經搜索了幾天并且找不到我想要做的確切答案。
所以,基本上我正在嘗試開發一個簡單的 Chrome 擴展來檢查Reddit上的用戶是否是機器人。擴展將:
- 使用document.querySelectorAll從當前執行緒獲取所有用戶;
- 從 reddit 獲取用戶個人資料;
- 檢查哪些用戶是機器人;
- 將[BOT]標簽附加到所有識別的機器人。
起初我試圖在我的background.js中做這樣的事情:
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (changeInfo.status === 'complete'){
chrome.scripting.executeScript({
target: { tabId: tabId},
func: getAuthors,
},
(authors) =>{
authors.forEach(element => {
getAbout(element).then(about =>{
getComments(element).then(comments =>{
isBot(about,comments).then(response =>{
//ADD TAG
});
});
});
});
})
}
});
The function getAuthors is able to sucessfully access the document and retrieve the data, the problem happens when I have to access it again to append the tags.
Storing an array of authors and passing it in another chrome.scripting.executeScript doesn't work, since the execution won't wait for the first chrome.scripting.executeScript to finish and will execute it immediately.
I've tried inverting the logic and use messaging as well, this time in my contentScript.js:
chrome.runtime.sendMessage('get-names', (names) => {
console.log('received user data', names);
names.forEach(element => {
element.parentElement.appendChild(tag);
});
});
現在我有一種附加標簽的方法,但我不能首先發送資料來處理它,因為據我所知,你只能在response上發送有效負載。如果我從我的background.js發送一條訊息,我最終會陷入與腳本及其異步執行類似的情況。
是否有捷徑可尋?
uj5u.com熱心網友回復:
雖然可以使用后臺腳本來實作此任務,但更簡單更好的解決方案是在內容腳本中執行所有操作。
內容腳本可以立即對 DOM 進行更改,并且可以向當前站點的 URL 發出網路請求以獲取用戶的詳細資訊。網路請求將是異步的,否則會在頁面加載中引入令人不快的延遲。
以下是整體方案:
- 內容腳本在
document_startDOM 為空時加載。 - 它讀取之前存盤的關于它過去檢查過的用戶的資料。這里最好的存盤是站點自己的
window.localStorage,因為它是同步的并且屬于同一個內部選項卡行程,因此讀取速度很快。 - 用于
MutationObserver檢測<a>頁面加載時添加的元素以及之后添加的元素,以支持新的 reddit UI(它動態構建頁面)和自動擴展舊 reddit UI 中的執行緒的各種用戶腳本/擴展。 - 對于每個匹配的元素,獲取快取的資料。
- 如果不存在,則發出網路請求,應用結果,將其存盤在存盤中。
清單.json:
{
"content_scripts": [{
"matches": ["*://www.reddit.com/*", "*://old.reddit.com/*"],
"js": ["content.js"],
"css": ["content.css"],
"run_at": "document_start"
}],
內容.css:
a.is-bot::after {
content: '[BOT]';
color: red;
margin-left: .25em;
}
內容.js:
const CLASS = 'is-bot';
const LS_KEY = 'b:';
const USER_URL = location.origin '/user/';
const SEL = `a[href^="/user/"], a[href^="${USER_URL}"]`;
const checkedElems = new WeakSet();
const promises = {};
new MutationObserver(onMutation)
.observe(document, {subtree: true, childList: true});
function onMutation(mutations) {
for (const {addedNodes} of mutations) {
for (const n of addedNodes) {
const toCheck = n.tagName === 'a'
? n.href.startsWith(USER_URL) && [n]
: n.firstElementChild && n.querySelectorAll(SEL);
for (const el of toCheck || []) {
if (checkedElems.has(el)) continue;
checkedElems.add(el);
const name = el.href.slice(USER_URL.length);
const isBot = localStorage[LS_KEY name];
if (isBot === '1') {
el.classList.add(CLASS);
} else if (isBot !== '0') {
(promises[name] || (promises[name] = checkUser(el, name)))
.then(res => res && el.classList.add(CLASS));
}
}
}
}
}
async function checkUser(el, name) {
const isBot = await (await fetch(API_URL name)).json();
localStorage[LS_KEY name] = isBot ? '1' : '0';
delete promises[name];
return isBot;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/434638.html
標籤:javascript 谷歌浏览器 chrome 扩展清单-v3
