简体   繁体   English

Cross Origin Chrome扩展程序

[英]Cross Origin Chrome Extension

I have been reading and playing around with Chrome Extensions for the last week or so but I'm having trouble trying to achieve what I want. 在过去一周左右的时间里,我一直在阅读和玩Chrome Extensions,但我在努力实现我想要的东西时遇到了麻烦。 What I am trying to create is an Extension that in the background (or silently) visits a website fills out a form on the web page and retrieves the response. 我想要创建的是一个扩展,在后台(或默默地)访问网站填写网页上的表单并检索响应。 The website doesn't have an API and I can't create a server to do this as the website only allows X requests per IP per hour so my requests would be exhausted after a few users. 该网站没有API,我无法创建服务器来执行此操作,因为该网站仅允许每小时每个IP的X请求,因此我的请求将在少数用户之后耗尽。

So my idea was to create a background page that would have some javascript to fill out the form using JS to getElementById, set the values, submit the form and return the response to the user seamlessly. 所以我的想法是创建一个后台页面,该页面将使用JS来填充表单,使用JS来getElementById,设置值,提交表单并将响应无缝地返回给用户。

After testing it seems the Same Origin policy is blocking me. 经过测试,似乎同源政策阻止了我。 Here's my code: 这是我的代码:

_ _

manifest.json 的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"
    }
}

Page.HTML: page.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: CO-TEST-FRAME.HTML:

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

myJS.js: 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);
}

When line 9, 10, 11, 14 is commented out I get "Some Text" as expected ie the local frame works fine. 当第9,10,11,14行被注释掉时,我按预期获得“Some Text”,即本地框架正常工作。 However when I uncomment those lines the second frame (on a server) throws the following error 但是,当我取消注释这些行时,第二帧(在服务器上)会引发以下错误

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.

I understand why this is blocked (due to people being able to run JS with malicious intent) but AFAIK background pages are run in an isolated environment so all risk is mitigated anyway? 我理解为什么这会被阻止(由于人们能够以恶意的方式运行JS),但AFAIK背景页面是在隔离的环境中运行的,所以所有风险都可以减轻? Is there any way to circumvent the Same-Origin policy or do what I am trying to achieve in another way? 有没有办法绕过同源政策或以其他方式做我想要实现的目标? Possibly with a content script and a 1x1 iframe on the user page? 可能在用户页面上有内容脚本和1x1 iframe?

There seems to be no way to circumvent the Same-origin policy for extension pages. 似乎没有办法绕过扩展页面的同源策略。 See https://bugs.chromium.org/p/chromium/issues/detail?id=344341 . 请参阅https://bugs.chromium.org/p/chromium/issues/detail?id=344341

You can achieve your objective by injecting a content script into the iframe on your background page and accessing and manipulating the iframe DOM using the content script. 您可以通过将内容脚本注入背景页面上的iframe并使用内容脚本访问和操作iframe DOM来实现您的目标。

A trivial example: 一个简单的例子:

Add the following to your manifest.json : 将以下内容添加到manifest.json

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


contentScript.js: contentScript.js:

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

Note that there is no window.onload in the content script. 请注意,内容脚本中没有window.onload Content scripts are injected after the DOM has loaded be default, so the window.onload event would not trigger. 在DOM加载后默认注入内容脚本,因此不会触发window.onload事件。

In case some communcation between the background page and the content script is needed, you will need to employ message passing . 如果需要在后台页面和内容脚本之间进行某些通信,则需要使用消息传递 There are many questions related to that on SO. 有关SO的问题有很多。

You need to explicitly list all the URLs under permissions in manifest.js Trying to use anything which is not listed would cause a Cross origin error. 您需要明确列出manifest.js中权限下的所有URL。尝试使用未列出的任何内容都会导致Cross origin错误。

you can list the url under permissions section and that should work. 你可以列出权限部分下的网址,这应该有效。

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

Hope that helps 希望有所帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM