Friday, May 17, 2024
124
rated 0 times [  129] [ 5]  / answers: 1 / hits: 40310  / 13 Years ago, sat, october 8, 2011, 12:00:00

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.).



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.



If there isn't, I'm going to make options.html contain an iframe that houses the layout and logic of the page.


More From » google-chrome

 Answers
24

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.


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://...").


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.



Note

To enable cross-origin requests, you have to explicitly grant permissions to your extension using the permissions array in your manifest file.



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*/
});

Background / event page:


/**
* 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
}
});

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
}
}

[#89724] Thursday, October 6, 2011, 13 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
herman

Total Points: 110
Total Questions: 90
Total Answers: 108

Location: Bosnia and Herzegovina
Member since Thu, Jun 24, 2021
3 Years ago
;