使用后台页面的跨域XMLHttpRequest
Cross-domain XMLHttpRequest using background pages
在我的Chrome扩展中,我想让我的options.html
页面与Google的OpenId API之类的东西进行通信。为了无缝地做到这一点,我在选项页面上有一个隐藏的iframe
,它将弹出谷歌账户登录页面(遵循OpenId交互序列等(
我的问题是,我无法通过window.postMessage
从选项页面与iframe
通信(iframe
的起源是我控制的,但与我的chrome扩展不同(。我想知道这个问题是否有一个快速的解决办法。
如果没有,我将使options.html
包含一个包含页面布局和逻辑的iframe
。
您不必使用iframe。可以使用后台页面执行跨域XMLHttpRequest。自Chrome 13以来,可以从内容脚本中进行跨站点请求。但是,如果页面带有带有限制connect-src
的内容安全策略标头,则请求仍然可能失败。
选择nexty方法而不是内容脚本的另一个原因是,对http网站的请求将导致混合内容警告(https://...显示了来自的不安全内容http://..."(。
将请求委派到后台页面的另一个原因是,当您希望从file://
获取资源时,因为内容脚本无法从file:
读取,除非它在file://
方案的页面上运行。
注意
要启用跨源请求,必须使用清单文件中的permissions
数组显式授予扩展名权限。
使用后台脚本的跨站点请求
内容脚本将通过消息API从后台请求功能。下面是一个发送和获取请求响应的非常简单的方法的示例。
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版本,请查看这个答案。
为了完整起见,这里有一个清单文件来试用我的演示:
{
"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
}
}
我使用jquery实现了同样的东西——它简单得多,工作也很好。。
background.js
chrome.runtime.onMessage.addListener(function(request, sender, callback) {
if (request.action == "xhttp") {
$.ajax({
type: request.method,
url: request.url,
data: request.data,
success: function(responseText){
callback(responseText);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
//if required, do some error handling
callback();
}
});
return true; // prevents the callback from being called too early on return
}
});
contentscript.js
chrome.runtime.sendMessage({
method: 'POST',
action: 'xhttp',
url: 'http://example-url.com/page.php',
data: "key=value"
}, function(reponseText) {
alert(responseText);
});
但请确保manifest.json文件具有所需的权限和jquery js文件
"permissions": [
"tabs", "activeTab", "http://example-url.com/*"
],
"content_scripts": [ {
"js": [ "jquery-3.1.0.min.js", "contentscript.js" ],
"matches": [ "https://example-ssl-site.com/*" ]
}],
"background": {
"scripts": [ "jquery-3.1.0.min.js", "background.js" ]
}
- XMLHttpRequest未返回值-状态202
- XMLHttpRequest在移动设备上的chrome上不起作用
- AJAX简单错误.XMLHttpRequest无法加载http://localhost/mpl/getPage.php.
- 检查xmlhttprequest问题的消息
- 主线程上的同步XMLHttpRequest已弃用
- 如何定期发出xmlhttprequest
- javascript第三个XMLHttpRequest被拒绝.但前两个是允许的
- 上传带有XMLHttprequest的文件-多部分/表单数据中缺少边界
- 对象#<XMLHttpRequest>没有方法'完成'
- 在XMLHttpRequest之后重新初始化jQuery
- 如何将GreaseMonkey中的XMLHttpRequest延迟到目标页面加载完成
- Javascript XMLHttpRequest——只有第一个POST请求有效
- XMLHttpRequest - difference between Chrome & Firefox
- IE上的新XMLHttpRequest()出现JS Ajax未指定错误
- 非常简单的XMLHttpRequest不起作用
- 如何使用XMLHttpRequest下载文件
- XMLHttpRequest在$.ajax工作的地方给出了CORS错误
- XMLHttpRequest.open()AJAX中的参数url
- XMLHTTPRequest脚本中没有internet连接和超时
- 为什么当async标志设置为false时,xmlhttprequest中的代码可以工作,而当它设置为true时却不能工作