How do I send a cross-domain POST request via JavaScript?

Viewed 576400

How do I send a cross-domain POST request via JavaScript?

Notes - it shouldn't refresh the page, and I need to grab and parse the response afterwards.

17 Answers
  1. Create an iFrame,
  2. put a form in it with Hidden inputs,
  3. set the form's action to the URL,
  4. Add iframe to document
  5. submit the form

Pseudocode

 var ifr = document.createElement('iframe');
 var frm = document.createElement('form');
 frm.setAttribute("action", "yoururl");
 frm.setAttribute("method", "post");

 // create hidden inputs, add them
 // not shown, but similar (create, setAttribute, appendChild)

 ifr.appendChild(frm);
 document.body.appendChild(ifr);
 frm.submit();

You probably want to style the iframe, to be hidden and absolutely positioned. Not sure cross site posting will be allowed by the browser, but if so, this is how to do it.

If you have access to all servers involved, put the following in the header of the reply for the page being requested in the other domain:

PHP:

header('Access-Control-Allow-Origin: *');

For example, in Drupal's xmlrpc.php code you would do this:

function xmlrpc_server_output($xml) {
    $xml = '<?xml version="1.0"?>'."\n". $xml;
    header('Connection: close');
    header('Content-Length: '. strlen($xml));
    header('Access-Control-Allow-Origin: *');
    header('Content-Type: application/x-www-form-urlencoded');
    header('Date: '. date('r'));
    // $xml = str_replace("\n", " ", $xml); 

    echo $xml;
    exit;
}

This probably creates a security problem, and you should make sure that you take the appropriate measures to verify the request.

  1. Create two hidden iframes (add "display: none;" to the css style). Make your second iframe point to something on your own domain.

  2. Create a hidden form, set its method to "post" with target = your first iframe, and optionally set enctype to "multipart/form-data" (I'm thinking you want to do POST because you want to send multipart data like pictures?)

  3. When ready, make the form submit() the POST.

  4. If you can get the other domain to return javascript that will do Cross-Domain Communication With Iframes (http://softwareas.com/cross-domain-communication-with-iframes) then you are in luck, and you can capture the response as well.

Of course, if you want to use your server as a proxy, you can avoid all this. Simply submit the form to your own server, which will proxy the request to the other server (assuming the other server isn't set up to notice IP discrepancies), get the response, and return whatever you like.

If you have access to the cross domain server and don't want to make any code changes on server side, you can use a library called - 'xdomain'.

How it works:

Step 1: server 1: include the xdomain library and configure the cross domain as a slave:

<script src="js/xdomain.min.js" slave="https://crossdomain_server/proxy.html"></script>

Step 2: on cross domain server, create a proxy.html file and include server 1 as a master:

proxy.html:
<!DOCTYPE HTML>
<script src="js/xdomain.min.js"></script>
<script>
  xdomain.masters({
    "https://server1" : '*'
  });
</script>

Step 3:

Now, you can make an AJAX call to the proxy.html as endpoint from server1. This is bypass the CORS request. The library internally uses iframe solution which works with Credentials and all possible methods: GET, POST etc.

Query ajax code:

$.ajax({
        url: 'https://crossdomain_server/proxy.html',
        type: "POST",
        data: JSON.stringify(_data),
        dataType: "json",
        contentType: "application/json; charset=utf-8"
    })
    .done(_success)
    .fail(_failed)
Related