2015-01-19 10 views
6

Ich habe Probleme beim Laden und Ausführen von externen js-Skript in meine Chrome-Erweiterung. Sieht genauso aus wie this question, aber ich kann immer noch nicht herausfinden, warum es in meinem Fall nicht funktioniert.Chrome-Erweiterung: Laden und Ausführen von externen Skript

Die Idee ist, dass ich in meinem Inhaltsskript eine Standardfunktion haben möchte, die einen Webseiteninhalt analysieren soll. Und für einige spezifische Webseiten möchte ich spezielle Parser laden und benutzen, also versuche ich, das richtige js-Skript für eine Wep-Seite zu laden, und dieses Skript sollte die Funktionalität des Standard-Parsers erweitern.

Inzwischen versuche ich nur Code von einem externen Skript ausführen, aber solche Fehler haben: Unchecked runtime.lastError while running tabs.executeScript: No source code or file specified at Object.callback

Das ist mein manifest.json:

{ 
"name": "Extension name", 
"version": "1.2", 
"description": "My chrome extension", 
"browser_action": { 
    "default_popup": "popup.html", 
}, 
"content_scripts": [{ 
    "css": [ 
     "style.css" 
    ], 
    "js": [ 
     "bower_components/jquery/dist/jquery.js", 
     "bower_components/bootstrap/dist/js/bootstrap.js", 
     "content.js" 
    ], 
    "matches": ["*://*/*"] 
}], 
"web_accessible_resources": [ 
    "frame.html", 
    "logo-48.png" 
], 
"icons": { 
    "16": "logo-16.png", 
    "48": "logo-48.png", 
    "128": "logo-128.png" 
}, 
"permissions": [ 
    "tabs", 
    "storage", 
    "http://*/", 
    "https://*/" 
], 
"manifest_version": 2 

}

Dies ist Popup .html

<!doctype html> 
<html> 
<head> 
    <title>Title</title> 
    <script src="popup.js"></script> 
</head> 
<body> 
    <ul> 
    <li>Some link</li> 
    </ul> 
</body> 
</html> 

Und in popup.js i ausführen Scrip wie folgt aus:

chrome.tabs.query({active: true, currentWindow: true}, function(tabs) { 
    chrome.tabs.executeScript(tabs[0].id, {file: "http://127.0.0.1:8000/static/plugin/somesite.js"}); 
}); 

Was bin ich dong falsch, habe ich etwas verpasst? Oder sollte ich einen anderen Ansatz verwenden, um das Problem zu lösen?

+0

Anmerkung (nicht mit Ihrem Fehler verbunden): '" http: // */"' stimmt NUR Top-Level-Seiten. Sie können entweder '" "' für eine breite Erlaubnis oder '" activeTab "' wenn Sie nur Zugriff auf die aktuelle Registerkarte benötigen. – Xan

+0

Gibt es einen Grund, warum Sie 'somesite.js' nicht in Ihre Erweiterung laden können? – Teepeemm

+0

Zum Abfangen von lastError, siehe https://StackOverflow.com/a/45603880/632951 – Pacerier

Antwort

6

Das Ausführen von Skripts aus externen Quellen, wie Sie es versuchen, ist von Google Chrome verboten und wird Ihre Erweiterung blockieren oder sogar nicht veröffentlichen. Alle Skripte müssen in der Erweiterung sein. Aber es gibt eine Lösung, from google chrome doc:

The restriction against resources loaded over HTTP applies only to those resources which are directly executed. You're still free, for example, to make XMLHTTPRequest connections to any origin you like; the default policy doesn't restrict connect-src or any of the other CSP directives in any way.

Wenn Sie schlecht eine externe Quelle benötigen, können Sie eine XML-HTTP-Anforderung tun und die eval auf den Inhalt verwenden. Hier ist ein Teil des Codes from google doc:

var xhr = new XMLHttpRequest(); 
xhr.open("GET", "http://127.0.0.1:8000/static/plugin/somesite.js", true); 
xhr.onreadystatechange = function() { 
    if (xhr.readyState == 4) { 
     // WARNING! Might be evaluating an evil script! 
     var resp = eval("(" + xhr.responseText + ")"); 
     // Or this if it's work 
     chrome.tabs.executeScript(tabs[0].id, {code: xhr.responseText}); 
    } 
} 
xhr.send(); 

oder können Sie etwas Bibliothek verwenden, $.get() with jquery oder $http with angularjs. , wenn Sie in Ihrem Code eval fügen Sie in manifest.json diesem hinzufügen:

"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"`, 
5

Gemäß der Diskussion hier: https://groups.google.com/a/chromium.org/forum/#!topic/chromium-extensions/LIH7LGXeQHo,

Running scripts from external sources may cause your extension to be unpublished or blocked.

einfach einen anderen Ansatz bietet, könnten Sie einen Ajax-Aufruf machen zum Inhalt Skript aufrufen dann chrome.tabs.executeScript

chrome.tabs.query({active: true, currentWindow: true}, function(tabs) { 
    $.get("http://127.0.0.1:8000/static/plugin/somesite.js", function(result) { 
     chrome.tabs.executeScript(tabs[0].id, {code: result}); 
    }, "text"); 
}); 
+1

Kann das Herunterladen und Ausführen eines Skripts nicht als 'Ausführen von Skripten von externen Quellen' betrachtet werden? Ist es von Google erlaubt? – Kolyunya

1

‚Datei‘ Option für ExecuteScript bezieht sich nur auf Dateien in Ihrer Erweiterung eingebettet. Ich weiß, the documentation ist nicht klar, und während es mit URLs funktionieren könnte, klingt es wie ein Hack, kein Feature. Um Skripte von externen Quellen in Ihre aktive Seite zu laden, müssen Sie normalerweise ein Skript ausführen, das ein Skript-Tag im DOM des geladenen Dokuments erstellt.

Ich glaube, ich habe Teile dieser Frage vor hier beantwortet: Why is chrome.tabs.executeScript() necessary to change the current website DOM and how can I use jQuery to achieve the same effect?

Fassen wir zusammen:

1), um von der Erweiterung Zugriff auf Webseiten zu haben, müssen Sie permissions für ihn hinzuzufügen:

"permissions" : [ 
     "tabs", 
     [...] 
     "http://*/*", 
     "https://*/*" ], 

2) Sie müssen irgendeine Art von Code auszuführen, die das DOM Script-Element erstellt, das lädt, was Sie brauchen:

chrome.tabs.executeScript(tab.id, { 
    code : 'var script=document.createElement(\'script\');' + 
    'script.onload=function() { /*do something in the page after the script was loaded*/ };' + 
    'script.src=\'http://127.0.0.1:8000/static/plugin/somesite.js\';' + 
    'document.body.appendChild(script);' 
}, function (returnedValue) { 
    // do something in the extension context after the code was executed 
}); 

Werfen Sie einen Blick auf die remex Funktion in den Link oben, die ich denke, löst eine Menge der Hässlichkeit von Javascript als String geschrieben wie hier.

+0

Aber das wird nicht als Erweiterungscode ausgeführt. Es wird als JavaScript der Seite ausgeführt. – golddove