2013-10-25 27 views
2

我是JavaScript新手,試圖學習Chrome擴展。我搜索了我能想到的所有問題的變體,但我發現的答案對我的具體問題無效。我已經瀏覽了Chrome擴展的教程,我認爲應該工作的實際上並不工作。在Chrome擴展中,content_scripts匹配被忽略

我寫的擴展沒有html頁面,只是一個圖標,因爲它應該始終運行。它實際上完美地工作,阻止對特定聊天程序的調用,以防止聊天窗口打開。它是爲那些必須長時間在網站上並且不想關閉聊天窗口的測試人員編寫的。

問題是,該擴展適用於所有網站,我只希望它適用於一個網站。也就是說,當用戶在使用相同聊天軟件的其他網站上時,聊天窗口也被阻止。

我讀過的內容導致我相信,將匹配放入我想要在manifest.json的content_scripts塊中使用的網站會導致擴展只能在匹配的網站中運行。這是行不通的。實際上,如果我完全將manifest_scripts塊從清單文件中取出,那麼擴展的工作原理完全相同。 javascript函數被調用並且聊天窗口被阻止。所以出於某種原因content_scripts塊被忽略。作爲一個javascript noob,我想我必須錯過一個關鍵的步驟。我從例子中得到了大部分代碼,並且稍微修改了它。誰能幫忙?

manifest.json的:

{ 
    "manifest_version": 2, 
    "version": "1.0", 
    "name": "ChatBlock", 
    "description": "Shut down liveperson chat on mywebsite.com before it runs.", 

    "permissions": [   
    "tabs", 
    "webRequest", 
    "webRequestBlocking", 
    "*://sales.liveperson.net/" 
    ], 
    "web_accessible_resources": ["jquery-1.10.2.min.js"], 
    "content_scripts": [ 
    { 
     "matches": ["*://*.mywebsite.com/*"], 
     "js": ["jquery-1.10.2.min.js"] 
    } 
    ], 
    "browser_action": { 
    "default_icon": "chatblockIcon.png" 
    }, 
    "background": { 
    "scripts": ["avoid.js"] 
    } 

    } 

JavaScript文件(avoid.js):

chrome.webRequest.onBeforeRequest.addListener(
    function(details) { 
    return { 
     cancel: true 
     }; 
    }, 
    {urls: ["*://sales.liveperson.net/*"]}, 
    ["blocking"]); 

編輯:我從清單移除jQuery的引用。該工具仍然工作沒有它只是相同的,所以下面的評論是正確的,這是不需要的 - 謝謝@ExpertSystem。但是所有網站仍然會發生阻止。我以前(在發佈這個問題之前)嘗試過@ ExpertSystem的第二個明確的建議,檢查所需網站的選項卡,或者檢查引用者,但我無法找到正確的JavaScript語法來使其工作。另外,如果可能的話,我對使用「匹配」屬性非常感興趣,所以javascript更通用。我仍然困惑爲什麼「比賽」不起作用 - 我對比賽屬性做錯了什麼?

manifest.json的新版本:

{ 
    "manifest_version": 2, 
    "version": "1.0", 
    "name": "ChatBlock", 
    "description": "Shut down liveperson chat on myWebsite.com before it runs.", 

    "permissions": [   
    "tabs", 
    "webRequest", 
    "webRequestBlocking", 
    "*://sales.liveperson.net/" 
    ], 
    "content_scripts": [ 
    { 
     "matches": ["*://*.myWebsite.com/*"], 
     "js": ["avoid.js"] 
    } 
    ], 
    "browser_action": { 
    "default_icon": "chatblockIcon.png" 
    }, 
    "background": { 
    "scripts": ["avoid.js"] 
    } 

    } 
+0

感謝,@ExpertSystem,爲您的評論。根據你的建議,我刪除了manifest.json中的jquery,因爲你似乎在說我在使用的小javascript代碼片段中並不需要它。看到我上面的編輯。我仍然對理解content_scripts塊中「匹配」屬性不起作用的原因感興趣。我使用不正確? – hengist

+0

您的「matches」屬性確實有效,但將'avoid.js'注入爲內容腳本沒有任何效果,因爲'chrome.webRequest'對內容腳本不可用。您在後臺頁面中的「avoid.js」確實有效,但無法區分請求的來源,因此它們會阻止從** all **標籤中對liveperson.com的請求。 (順便說一下,運行與內容腳本相同的腳本和背景頁面是一個不錯的主意。) – gkalpak

+0

另請參閱我的更新答案。 – gkalpak

回答

2

您注射的jQuery的內容腳本,但她自己的,她也沒用。另外,您正在監聽背景頁面中的webRequests到liveperson.com,併爲每個站點取消它們。

您必須設法區分來自mywebsite.com的請求,並且只能阻止它們。 (我,也看不出有任何理由注射jQuery的。)

可能的方式來區分請求可能是:

  1. 通過一個頭在details.requestHeaders(如果mywebsite.com套這樣一個適當的標題,如referer )。
  2. 跟蹤在後臺頁面中運行mywebsite.com的打開標籤(通過chrome.tabs.onUpdated聽衆)並根據details.tabId過濾web請求。

......但我相信還有更多。


我的演示實現上述第二個選項...

manifest.json的:

... 
"background": { 
    // Unfortunately, chrome.webRequest 
    // requires a persistent background page 
    "persistent": true, 
    "scripts": [ 
     "background.js" 
    ] 
}, 

"content_scripts": [ 
    { 
     "matches": [ 
      "*://<website1>/*", 
      "*://<website2>/*", 
      ... 
     ], 
     "js":   ["content.js"], 
     "run_at":  "document_idle", 
     "all_frames": false 
    } 
], 

"permissions": [ 
    "webRequest", 
    "webRequestBlocking", 
    "*://sales.liveperson.net/*" 
] 

content.js:

chrome.runtime.sendMessage({ text: "block_me" }); 

BAC kground.js:

// Add a tab ID to the blocking list 
function addToList(tabId) { 
    localStorage.setItem(tabId, "1"); 
    console.log("Added to list: tab " + tabId); 
    console.log("Currently blocking tabs: ", localStorage); 
} 

// Checks if a tab ID is in the blocking list 
function isInList(tabId) { 
    return (localStorage.getItem(tabId) !== null); 
} 

// Remove a tab ID from the blocking list 
function removeFromList(tabId) { 
    localStorage.removeItem(tabId); 
    console.log("Removed from list: tab " + tabId); 
    console.log("Currently blocking: ", localStorage); 
} 

// Listen for messages from content scripts 
chrome.runtime.onMessage.addListener(function(msg, sender) { 
    if (msg.text && (msg.text == "block_me")) { 
     addToList(sender.tab.id); 
    } 
}); 

// Stop blocking a tab when its is closed 
chrome.tabs.onRemoved.addListener(removeFromList); 

// Stop blocking a tab when its is updated 
// (If applicable, the newly injected content script will notify us.) 
chrome.tabs.onUpdated.addListener(function(tabId, info, tab) { 
    if (info.status && (info.status == "loading")) { 
     removeFromList(tabId); 
    } 
}); 


// Handle a web-request, i.e. either allow it or block it 
function handleRequest(details) { 
    var block = isInList(details.tabId); 
    console.log("Request from tab " + details.tabId + " - Blocked: " + block); 
    console.log("Request details: ", details); 
    return { cancel: block }; 
} 

// Block any request to 'sales.liveperson.net', 
// if it originates from a tab in our blocking list. 
chrome.webRequest.onBeforeRequest.addListener(
     handleRequest, 
     { urls: ["*://sales.liveperson.net/*"] }, 
     ["blocking"]); 

(對於生產部署,您可以刪除console.log電話。)