2

Ich habe in den letzten Wochen mit Chrome Extensions gelesen und gespielt, aber ich habe Probleme damit, das zu erreichen, was ich möchte. Was ich versuche zu erstellen, ist eine Extension, die im Hintergrund (oder stillschweigend) eine Website besucht, ein Formular auf der Webseite ausfüllt und die Antwort abruft. Die Webseite hat keine API und ich kann keinen Server dafür erstellen, da die Webseite nur X Anfragen pro IP pro Stunde erlaubt, so dass meine Anfragen nach ein paar Benutzern erschöpft sind.Cross Origin Chrome Extension

Also war meine Idee, eine Hintergrundseite zu erstellen, die etwas Javascript haben würde, um das Formular auszufüllen, das JS zu GetElementById verwendet, die Werte festlegt, das Formular absendet und die Antwort nahtlos an den Benutzer zurückgibt.

Nach dem Testen scheint es, dass die Same Origin-Richtlinie mich blockiert. Hier ist mein Code:

_

manifest.json

{ 
    "manifest_version": 2, 

    "name": "Getting started example", 
    "description": "This extension shows a Google Image search result for the current page", 
    "version": "1.0", 

    "permissions": [ 
    "activeTab", "webRequest", "webRequestBlocking", 
    "https://ajax.googleapis.com/" 
    ], 
    "background": { 
     "page": "Page.html" 
    } 
} 

seite.html:

<html> 
    <head> 

     <script src="myJS.js"></script> 

    </head> 

    <body> 
     <iframe src="CO-TEST-FRAME.html" width="400" height="400" id="maniframe" class="maniframe"></iframe> 
     <iframe src="http://www.myserver.com/iframe/CO-TEST-FRAME.html" width="400" height="400" id="maniframe2" class="maniframe2"></iframe> 
     <p id="test">new</div> 
    </body> 
</html> 

CO-TEST-frame.html:

<html> 
    <head> 
    </head> 

    <body> 
     <div id="desired" class="desired" hidden="hidden">some text</div> 
    </body> 
</html> 

myJS .js:

window.onload = function() { 

    alert("working"); 

    var iframe = document.getElementById("maniframe"); 
    var iframeStuff = iframe.contentDocument || iframe.contentWindow.document; 
    var test = iframeStuff.getElementById("desired").innerHTML; 

    var iframe2 = document.getElementById("maniframe2"); 
    var iframeStuff2 = iframe2.contentDocument || iframe.contentWindow.document; 
    var test2 = iframeStuff.getElementById("desired").innerHTML; 

    console.log(test); 
    console.log(test2); 

} 

Wenn Zeile 9, 10, 11, 14 auskommentiert ist, bekomme ich "Some Text" wie erwartet, d. H. Der lokale Rahmen funktioniert gut. Jedoch, wenn ich diese Zeilen der zweite Rahmen (auf einem Server) Kommentar- führt den folgenden Fehler

myJS.js:10 Uncaught SecurityError: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': Blocked a frame with origin "chrome-extension://laocffdoafnoeipdndafcdbiaaephcah" from accessing a frame with origin "http://www.myserver.com". The frame requesting access has a protocol of "chrome-extension", the frame being accessed has a protocol of "http". Protocols must match. 

Ich verstehe, warum diese blockiert wird (aufgrund Menschen JS ausführen zu können, mit böswilliger Absicht), aber AFAIK Hintergrund Seiten laufen in einer isolierten Umgebung, so dass jedes Risiko gemindert wird? Gibt es eine Möglichkeit, die Same-Origin-Richtlinie zu umgehen oder das zu tun, was ich auf andere Weise erreichen möchte? Möglicherweise mit einem Inhaltsskript und einem 1x1 iframe auf der Benutzerseite?

Vielen Dank im Voraus

+1

Es hilft besser wäre, wenn Sie Ihre 'manifest.json' bieten könnte. –

+0

hat es dem OP hinzugefügt. – YengSpiz

Antwort

3

Es scheint kein Weg, um den Same-Origin-Policy für die Erweiterung Seiten zu umgehen. Siehe https://bugs.chromium.org/p/chromium/issues/detail?id=344341.

Sie können Ihr Ziel erreichen, indem Sie eine content script in den iframe auf Ihrer Hintergrundseite einfügen und auf das iframe-DOM mit dem Inhaltsskript zugreifen und es bearbeiten.

Ein triviales Beispiel:

Fügen Sie folgendes zu Ihrem manifest.json:

"content_scripts": [ 
{ 
    "matches": ["http://www.myserver.com/iframe/CO-TEST-FRAME.html"], 
    "js": ["contentScript.js"], 
     "all_frames": true 
} 


contentScript.js:

console.log("Content script injected."); 
var test = document.getElementById("desired").innerHTML; 
console.log("Text from " + document.URL + ": " + test); 

Hinweis, dass es keine window.onload in den Inhalt ist Skript. Inhaltsskripts werden injiziert, nachdem das DOM standardmäßig geladen ist, sodass das Ereignis window.onload nicht ausgelöst wird.

Falls eine Kommunikation zwischen der Hintergrundseite und dem Inhaltsskript benötigt wird, müssen Sie message passing verwenden. Es gibt viele Fragen in Bezug auf SO.

0

Sie müssen explizit alle URLs unter den Berechtigungen in manifest.js aufführen. Der Versuch, alles zu verwenden, was nicht aufgeführt ist, würde einen Cross-Ursprungsfehler verursachen.

Sie können die URL unter Berechtigungen Abschnitt und das sollte funktionieren.

"permissions": [ 
     "webRequest", 
     "storage", 
     "https://mail.google.com/*", 
     "http://myserver.com/*", 
     "https://blah.blah.com/*" 
    ], 

Hoffnung, die