Yen*_*piz 5 javascript cross-domain same-origin-policy google-chrome-extension
在过去大约一周的时间里,我一直在阅读和使用Chrome扩展程序,但是在尝试实现自己想要的功能时遇到了麻烦。我要创建的是一个在后台(或无提示)访问网站的扩展程序,该程序在网页上填写表格并检索响应。该网站没有API,我无法创建服务器来执行此操作,因为该网站每小时仅允许每个IP X个请求,因此我的请求将在几个用户之后被耗尽。
因此,我的想法是创建一个后台页面,该页面将使用JS到getElementById的JS来填写表单,设置值,提交表单并将响应无缝返回给用户。
经过测试,似乎同源起源策略阻止了我。这是我的代码:
_
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"
}
}
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
CO-TEST-FRAME.HTML:
<html>
<head>
</head>
<body>
<div id="desired" class="desired" hidden="hidden">some text</div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
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);
}
Run Code Online (Sandbox Code Playgroud)
当第9、10、11、14行被注释掉时,我按预期得到“ Some Text”,即本地框架工作正常。但是,当我取消注释这些行时,第二帧(在服务器上)会引发以下错误
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.
Run Code Online (Sandbox Code Playgroud)
我知道为什么会阻止此操作(由于人们能够出于恶意意图运行JS),但是AFAIK后台页面在隔离的环境中运行,因此无论如何都可以减轻所有风险?有什么方法可以规避“原产地政策”,或者我想通过另一种方式来实现?可能在用户页面上使用了内容脚本和1x1 iframe?
似乎没有办法规避扩展页面的同源策略。请参阅https://bugs.chromium.org/p/chromium/issues/detail?id=344341。
您可以通过将内容脚本注入后台页面上的 iframe 并使用内容脚本访问和操作 iframe DOM 来实现您的目标。
一个简单的例子:
将以下内容添加到您的manifest.json:
"content_scripts": [
{
"matches": ["http://www.myserver.com/iframe/CO-TEST-FRAME.html"],
"js": ["contentScript.js"],
"all_frames": true
}
Run Code Online (Sandbox Code Playgroud)
内容脚本.js:
console.log("Content script injected.");
var test = document.getElementById("desired").innerHTML;
console.log("Text from " + document.URL + ": " + test);
Run Code Online (Sandbox Code Playgroud)
window.onload请注意,内容脚本中没有。默认情况下,内容脚本是在 DOM 加载后注入的,因此该window.onload事件不会触发。
如果后台页面和内容脚本之间需要进行一些通信,您将需要使用消息传递。SO 上有很多与此相关的问题。