views:

90

answers:

5

I swear I saw an article about this at one point but can not find it...

How can I perform a jQuery ajax request of type POST on another domain? Must be accomplished without a proxy. Is this possible?

+1  A: 

Yes you can POST all you want, even $.post() works...but you won't get a response back.

This works, the other domain will get the POST:

$.post("http://othersite.com/somePage.php", { thing: "value" }, function(data) {
  //data will always be null
});

But the response, data in the above example, will be null due to the same-origin policy.

Nick Craver
If I use $.post, would the request show up in firebug? I am trying it now but do not see anything.
Louis W
@Louis - The *request* yes, the *response* no, it's reflecting what your code's going to see...an empty response due to the SOP.
Nick Craver
@Louis - What are you sending btw? Is it something a GET can handle? Because you can pass additional parameters on the GET request with a JSONP request...a response which you can see. The other domain has to support this though.
Nick Craver
Sorry for the delay getting back to you, I did some testing and can not seem to get this to work. Javascript will do the post but not send any fields. I have uploaded a simplified example of how I am trying to do it here: http://loui5.com/tmp/js_xss_post/. I might also add, the request does not show up in firebug but I get it (the page emails me).
Louis W
A: 

If you want a fire and forget POST where you don't care about the response then just submit a form to a hidden iframe. This requires a Transitional Doctype.

<form method="POST" action="http://example.com/" target="name_of_iframe">

If you want to parse the response, then using a proxy if the only real option.

If you are desperate, and control the remote site, then you can:

  1. Submit a form as above
  2. Set a cookie in the response (which might be blocked before the iframe could cause the cookie to be considered '3rd party' (i.e. likely to be advertising tracking).
  3. Wait long enough for the response to come back
  4. Dynamically generate a script element with the src pointing to the remote site
  5. Use JSON-P in the response and take advantage of the data previously stored in the cookie

This approach is subject to race conditions and generally ugly. Proxing the data through the current domain is a much better approach.

David Dorward
Even this isn't needed though, any of the jQuery POST-ing AJAX functions work to accomplish the same thing a bit simpler.
Nick Craver
Those functions are, AFAIK, just a high level wrapper around generating an iframe. It's always useful to understand what the library is doing, so you can understand the limitations and deal with it when things go wrong.
David Dorward
@David - They do not use an `<iframe>` at all, they're using `XmlHttpRequest()`, the **POST** isn't blocked, only getting the response is.
Nick Craver
@David - I'm honestly curious where the generating an `<iframe>` idea for what jQuery does underneath came from, is there an article out there saying this, or some documentation that gives that impression?
Nick Craver
Looking into this. I also recall the ability to add an onload function to the iframe to talk back to parent to give the contents. Never tried that thou.
Louis W
@Nick — An assumption, clearly an incorrect one
David Dorward
@Louis — I wouldn't be surprised if it did fire when the iframe has finished loading, it won't let you get the content though.
David Dorward
A: 

If you have control over the code running at the other domain, just let it return an appropriate Access-Control-Allow-Origin header in the response. See also HTTP Access-Control at MDC.

BalusC
Browser support is rather limited for ACAO at the moment. I wouldn't want to use it in the wild.
David Dorward
@David: The OP just asked if it was possible without a proxy. I just answered that. The OP sweared he saw an article. I imagined that it was about `Access-Control` headers. Regardless, the browser support is present in almost all modern browsers/updates younger than 1 year.
BalusC
A: 

I've done something like that in the past, and I believe the answer was JSONP.

Making Cross Domain jQuery AJAX Calls

gjsduarte
JSONP will only work with GET requests.
Louis W
ups.. my bad then.
gjsduarte
A: 

All the options I've experimented with:

1) PORK: http://www.schizofreend.nl/Pork.Iframe/Examples/ Creates an iframe and submits the post there, then reads the response. Still requires same base domain per request (i.e. www.foo.com can request data from www2.foo.com, but not from www.google.com) . Also requires you to fiddle with the document.domain property, which causes adverse side effects. And there's a pervasive problem in all the major browsers where reloading the page basically shuffles the cached contents of all iframes on the page if any of them are dynamically written. Your response data will show up in the box where an ad is supposed to be.

2) flxhr: http://flxhr.flensed.com/ Can even be used to mask jQuery's built-in ajax so you don't even notice it. Requires flash though, so iPhone is out

3) jsonp: Doesn't work if you're posting a lot of data. boo.

4) chunked jsonp: When your jsonp request is too big, break the query string up into manageable chunks and send multiple get requests. Reconstruct them on the server. This is helpful but breaks down if you're load balancing users between servers.

5) CORS: http://www.w3.org/TR/cors/ doesn't work in older browsers (IE7, IE6, Firefox 2, etc)

So we currently do the following algorithm:

  • If request is small enough, use JSONP
  • If not small enough, but user has flash, use FlXHR
  • Else use chunked JSONP

Spend one afternoon writing that up and you'll be able to use it for good. Adding CORS to our algorithm might be good for faster iPhone support.

Mike Ruhlin