跨域XMLHttpRequest使用后台页面 [英] Cross-domain XMLHttpRequest using background pages
问题描述
在我的Chrome扩充功能中,我想让我的 options.html
网页与Google的OpenId API进行通讯。为了无缝地执行此操作,我在选项页面上有一个隐藏的 iframe
,将弹出Google帐户登录页面(遵循OpenId交互序列等)。
In my Chrome extension, I want to have my options.html
page communicate with something like Google's OpenId API. In order to do this seamlessly, I have a hidden iframe
on the options page which will pop-up the Google Accounts login page (following the OpenId interaction sequence, etc.).
我的问题是我无法从选项页面传送到 iframe
code> iframe 是我控制的,但不是我的chrome扩展)通过 window.postMessage
。我想知道是否有这个问题的快速解决方法。
My issue is that I can't communicate from the options page to the iframe
(the origin of the iframe
is something I control, but not the same as my chrome extension) via window.postMessage
. I was wondering if there is a quick workaround to this issue.
如果没有,我会使 options.html
包含一个包含页面布局和逻辑的 iframe
。
If there isn't, I'm going to make options.html
contain an iframe
that houses the layout and logic of the page.
推荐答案
您不必混淆iframe。可以使用后台网页执行跨网域XMLHttpRequests。自Chrome 13起,跨网站请求可以从内容脚本中创建。但是,如果该网页提供的内容安全策略标头的限制为 connect-src
。
You don't have to mess with iframes. It's possible to perform cross-domain XMLHttpRequests, using background pages. Since Chrome 13, cross-site requests can be made from the content script. However, requests can still fail if the page is served with a Content Security Policy header with a restricting connect-src
.
选择nexy方法而不是内容脚本的另一个原因是对http网站的请求将导致混合内容警告(该网页在https:// ...显示来自http:// ...的不安全内容)。
Another reason for choosing the nexy method over content scripts is that requests to http sites will cause a mixed content warning ("The page at https://... displayed insecure content from http://...").
将请求委托给后台页面的另一个原因是当你想从 file://
获取资源时,因为内容脚本不能从 file:
,除非它在 file://
方案的页面上运行。
Yet another reason for delegating the request to the background page is when you want to get a resource from the file://
, because a content script cannot read from file:
, unless it is running on a page at the file://
scheme.
请注意
要启用跨源请求,您必须使用<$ c $
Note
To enable cross-origin requests, you have to explicitly grant permissions to your extension using thepermissions
array in your manifest file.
使用后台脚本跨网站请求。 >
内容脚本会通过消息 API从后台请求功能。这是一个发送和获取请求响应的非常简单的方法的示例。
Cross-site request using background script.
The content script would request the functionality from the background via the messaging API. Here is an example of a very simple way of sending and getting the response of a request.
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版本,请查看此答案。
Remark: The messaging APIs have been renamed several times. If your target browser is not the latest Chrome version, check out this answer.
为了完整性,这里有一个清单文件,用于试用我的演示:
For completeness, here's a manifest file to try out my demo:
{
"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
}
}
这篇关于跨域XMLHttpRequest使用后台页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!