运行tabs.executeScript时未检查runtime.lastError?

我设法build立了Ripple模拟器开源( https://github.com/apache/incubator-ripple )。

我根据说明(Jake构build)构build了它,它创build了Chrome扩展目标,允许我通过构build的Chrome扩展来testing我的Web应用程序,按照https://github.com/apache/incubator-ripple/blob /master/doc/chrome_extension.md 。

我成功地将解压后的扩展加载到chrome上,但是当我启用它时,没有任何反应,虽然页面重新加载扩展不起作用,而是我得到2个错误:

  1. 未捕获的ReferenceError:未定义webkitNotifications

    webkitNotifications.createHTMLNotification('/views/update.html').show(); 
  2. 运行tabs.executeScript时未经检查的runtime.lastError:无法访问chrome:// URL

     chrome.tabs.executeScript(tabId, { 

我如何解决这个问题?


完整的background.js:

 if (!window.tinyHippos) { window.tinyHippos = {}; } tinyHippos.Background = (function () { var _wasJustInstalled = false, _self; function isLocalRequest(uri) { return !!uri.match(/^https?:\/\/(127\.0\.0\.1|localhost)|^file:\/\//); } function initialize() { // check version info for showing welcome/update views var version = window.localStorage["ripple-version"], xhr = new window.XMLHttpRequest(), userAgent, requestUri = chrome.extension.getURL("manifest.json"); _self.bindContextMenu(); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { var manifest = JSON.parse(xhr.responseText), currentVersion = manifest.version; if (!version) { _wasJustInstalled = true; } if (version !== currentVersion) { webkitNotifications.createHTMLNotification('/views/update.html').show(); } window.localStorage["ripple-version"] = currentVersion; } }; xhr.open("GET", requestUri, true); xhr.send(); chrome.extension.onRequest.addListener(function (request, sender, sendResponse) { switch (request.action) { case "isEnabled": console.log("isEnabled? ==> " + request.tabURL); sendResponse({"enabled": tinyHippos.Background.isEnabled(request.tabURL)}); break; case "enable": console.log("enabling ==> " + request.tabURL); tinyHippos.Background.enable(); sendResponse(); break; case "version": sendResponse({"version": version}); break; case "xhr": var xhr = new XMLHttpRequest(), postData = new FormData(), data = JSON.parse(request.data); console.log("xhr ==> " + data.url); $.ajax({ type: data.method, url: data.url, async: true, data: data.data, success: function (data, status) { sendResponse({ code: 200, data: data }); }, error: function (xhr, status, errorMessage) { sendResponse({ code: xhr.status, data: status }); } }); break; case "userAgent": case "lag": case "network": // methods to be implemented at a later date break; default: throw {name: "MethodNotImplemented", message: "Requested action is not supported!"}; break; }; }); chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) { if (tinyHippos.Background.isEnabled(tab.url)) { chrome.tabs.executeScript(tabId, { code: "rippleExtensionId = '" + chrome.extension.getURL('') + "';", allFrames: false }, function () { chrome.tabs.executeScript(tabId, { file: "bootstrap.js", allFrames: false }); }); } }); } function _getEnabledURIs() { var parsed = localStorage["tinyhippos-enabled-uri"]; return parsed ? JSON.parse(parsed) : {}; } function _persistEnabled(url) { var jsonObject = _getEnabledURIs(); jsonObject[url.replace(/.[^\/]*$/, "")] = "widget"; localStorage["tinyhippos-enabled-uri"] = JSON.stringify(jsonObject); } _self = { metaData: function () { return { justInstalled: _wasJustInstalled, version: window.localStorage["ripple-version"] }; }, bindContextMenu: function () { var id = chrome.contextMenus.create({ "type": "normal", "title": "Emulator" }); // TODO: hack for now (since opened tab is assumed to be page context was called from // eventually will be able to pass in data.pageUrl to enable/disable when persistence refactor is done chrome.contextMenus.create({ "type": "normal", "title": "Enable", "contexts": ["page"], "parentId": id, "onclick": function (data) { _self.enable(); } }); chrome.contextMenus.create({ "type": "normal", "title": "Disable", "contexts": ["page"], "parentId": id, "onclick": function (data) { _self.disable(); } }); }, enable: function () { chrome.tabs.getSelected(null, function (tab) { console.log("enable ==> " + tab.url); _persistEnabled(tab.url); chrome.tabs.sendRequest(tab.id, {"action": "enable", "mode": "widget", "tabURL": tab.url }); }); }, disable: function () { chrome.tabs.getSelected(null, function (tab) { console.log("disable ==> " + tab.url); var jsonObject = _getEnabledURIs(), url = tab.url; while (url && url.length > 0) { url = url.replace(/.[^\/]*$/, ""); if (jsonObject[url]) { delete jsonObject[url]; break; } } localStorage["tinyhippos-enabled-uri"] = JSON.stringify(jsonObject); chrome.tabs.sendRequest(tab.id, {"action": "disable", "tabURL": tab.url }); }); }, isEnabled: function (url, enabledURIs) { if (url.match(/enableripple=/i)) { _persistEnabled(url); return true; } // HACK: I'm sure there's a WAY better way to do this regex if ((url.match(/^file:\/\/\//) && url.match(/\/+$/)) || url.match(/(.*?)\. (jpg|jpeg|png|gif|css|js)$/)) { return false; } enabledURIs = enabledURIs || _getEnabledURIs(); if (url.length === 0) { return false; } else if (enabledURIs[url]) { return true; } return tinyHippos.Background.isEnabled(url.replace(/.[^\/]*$/, ""), enabledURIs); } }; initialize(); return _self; }()); 

完整的manifest.json:

 { "version": "1", "manifest_version": 2, "name": "Ripple Emulator (Beta)", "background": { "page": "views/background.html" }, "web_accessible_resources": [], "icons":{ "16":"images/Icon_16x16.png", "128":"images/Icon_128x128.png", "48":"images/Icon_48x48.png" }, "browser_action":{ "default_popup":"views/popup.html", "default_icon":"images/Icon_48x48.png", "default_title":"Ripple" }, "content_scripts":[{ "run_at": "document_start", "js": ["controllers/Insertion.js"], "matches": ["http://*/*","https://*/*","file://*"] }, { "run_at": "document_start", "js": ["controllers/frame.js"], "matches": ["http://*/*","https://*/*","file://*"], "all_frames": true }], "permissions": ["tabs", "unlimitedStorage", "notifications", "contextMenus", "webRequest", "<all_urls>"], "description": "A browser based html5 mobile application development and testing tool" } 

这两个错误都很好地解释了这个问题:

“webkitNotifications未定义” – 这是因为webkitNotifications已被删除。 我发现Chrome webkitNotification没有find:api丢失 ,解释发生了什么。

“无法访问chrome:// URL” – 您必须尝试在chrome:// URL(如chrome:// settings,chrome:// extensions)上执行该脚本,这是非法的。 为了避免这样的错误打印,你可以 – 检查chrome.runtime.lastError – 确保不要注入到chrome://页面。

通过在callback中“读取”它来“检查” runtime.lastError


 chrome.tabs.executeScript(tabId, { //.. }, _=>chrome.runtime.lastError /* "check" error */) 

例如

通过..显示

 chrome.tabs.executeScript(tabId, { //.. }, _=>{ let e = chrome.runtime.lastError; if(e !== undefined){ console.log(tabId, _, e); } }); 
Interesting Posts