Cross-domain XMLHttpRequest using background pages Cross-domain XMLHttpRequest using background pages google-chrome google-chrome

Cross-domain XMLHttpRequest using background pages


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


I implemented the same thing using jquery its much simpler and it worked great too..

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

But make sure manifest.json file has required permissions and jquery js file

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