在我的 Chrome 扩展程序中,我想让我的 options.html
页面与 Google 的 OpenId API 之类的东西进行通信。为了无缝执行此操作,我在选项页面上隐藏了一个 iframe
,它将弹出 Google 帐户登录页面(遵循 OpenId 交互序列等)。
我的问题是我无法从选项页面与 iframe
通信(iframe
的来源是我控制的,但与我的不同chrome 扩展)通过 window.postMessage
。我想知道这个问题是否有快速解决方法。
如果没有,我会让 options.html
包含一个 iframe
来容纳页面的布局和逻辑。
最佳答案
您不必乱用 iframe。可以使用后台页面执行跨域 XMLHttpRequests。从 Chrome 13 开始,可以从内容脚本发出跨站请求。但是,如果页面使用带有限制性 connect-src
的内容安全策略 header 提供,请求仍然会失败。 .
选择 nexy 方法而不是内容脚本的另一个原因是对 http 站点的请求将导致混合内容警告(“https://... 的页面显示来自 http://... 的不安全内容”) .
将请求委托(delegate)给后台页面的另一个原因是当您想要从 file://
获取资源时,因为内容脚本无法从 file:
读取, 除非它在 file://
的页面上运行方案。
Note
To enable cross-origin requests, you have to explicitly grant permissions to your extension using thepermissions
array in your manifest file.
使用后台脚本的跨站请求。
内容脚本将通过 messaging 从后台请求功能应用程序接口(interface)。这是发送和获取请求响应的非常简单的方法的示例。
chrome.runtime.sendMessage({
method: 'POST',
action: 'xhttp',
url: 'http://www.stackoverflow.com/search',
data: 'q=something'
}, function(responseText) {
alert(responseText);
/*Callback function to deal with the response*/
});
/**
* Possible parameters for request:
* action: "xhttp" for a cross-origin HTTP request
* method: Default "GET"
* url : required, but not validated
* data : data to send in a POST request
*
* The callback function is called upon completion of the request */
chrome.runtime.onMessage.addListener(function(request, sender, callback) {
if (request.action == "xhttp") {
var xhttp = new XMLHttpRequest();
var method = request.method ? request.method.toUpperCase() : 'GET';
xhttp.onload = function() {
callback(xhttp.responseText);
};
xhttp.onerror = function() {
// Do whatever you want on error. Don't forget to invoke the
// callback to clean up the communication port.
callback();
};
xhttp.open(method, request.url, true);
if (method == 'POST') {
xhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
}
xhttp.send(request.data);
return true; // prevents the callback from being called too early on return
}
});
备注:消息传递 API 已多次重命名。如果您的目标浏览器不是最新的 Chrome 版本,请查看 this answer .
为了完整起见,这里有一个 manifest文件来试用我的演示:
{
"name": "X-domain test",
"manifest_version": 2,
"permissions": [
"http://www.stackoverflow.com/search*"
],
"content_scripts": {
"js": ["contentscript.js"],
"matches": ["http://www.example.com/*"]
},
"background": {
"scripts": ["background.js"],
"persistent": false
}
}
关于javascript - 使用后台页面的跨域XMLHttpRequest,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7699615/