views:

3845

answers:

6

I need to make an AJAX request from a website to a REST web service hosted in another domain.


Althouht this is works just fine in Internet Explorer, other browsers such as Mozilla and Google Chrome impose far stricter security restrictions, which prohibit cross-site AJAX requests.

My problem is that I have no control over the domain nor the web server where the site is hosted. This means my REST web service must run somewhere else, and I can't put in place any redirection mechanism.
Here is the JavaScript code that makes the asynchronous call:

var serviceUrl = "http://myservicedomain";
var payload = "<myRequest><content>Some content</content></myRequest>";
var request = new XMLHttpRequest();
request.open("POST", serviceUrl, true); // <-- This fails in Mozilla Firefox amongst other browsers
request.setRequestHeader("Content-type", "text/xml");
request.send(payload);

How can have this work in other browsers than just Internet Explorer?

+5  A: 

maybe jsonp can help.

NB youll have to change your messages to use json instead of xml

Edit

Major sites such as flickr and twitter support jsonp with callbacks etc

redsquare
this might work, but JSONP is an admission that something's wrong :)
annakata
how popular is this approach? It seems kind of experimental.
Enrico Campidoglio
@annakata obviously but he metnioned he has no handle over the web server etc so using a proxy is out of the window. I'm not here to comment on his situation just provide a possible solution to his question/problem.
redsquare
@redsquare: agreed, he's in a corner@enrico: quite experimental, but it is used
annakata
Even though posting the AJAX request from an iframe hosted on the same domain as the REST service is a viable solution (as long as there is no need for communication between the iframe and the page), I'm not very fond of iframes in general because of their compatibility issues. So JSONNP is probably the best solution currently available.
Enrico Campidoglio
but from my understanding, jsonp requires the server embed a call to the "callback" function passed in the jsonp request, so this wouldn't work in this situation, since he doesn't have control over the server... read the following for a nice overview of jsonp: http://www.insideria.com/2009/03/what-in-the-heck-is-jsonp-and.html
Brad Parks
+1  A: 

The fact that this works in IE is a security issue with IE, not a feature.

Unfortunately cross-site scripting is prohibited, and the accepted work around is to proxy the requests through your own domain: do you really have no ability to add or modify server side code?

Furthermore, the secondary workaround - involving the aquisition of data through script tags - is only going to support GET requests, which you might be able to hack with a SOAP service, but not so much with the POST request to a RESTful service you describe.

I'm really not sure an AJAX solution exists, you might be back to a <form> solution.

annakata
I agree that allowing XSS is a security flaw in IE.Unfortunately, I don't have any control over the web server, since it is a blog hosted on a third-party provider.I also thought about using HTML forms, but that would cause a full page post instead of a nice asynchronous call.
Enrico Campidoglio
+1  A: 

Have you tried posting to an IFrame ?

You mean having the AJAX request made from an IFrame hosted on the same domain as the REST web service?
Enrico Campidoglio
There may be milage in this, but you're really just moving the problem not solving it - the iframe/page communication will now have an issue
annakata
That's OK since I don't need to access the parent page from the iframe, but just make an AJAX request with the iframe's own content.
Enrico Campidoglio
A: 

This post could be helpful for you.

Edit(Adam): Post was linked incorrectly, but points to a blank page anyway. Here's a more useful post on Firefox's implementation of the W3C "Access Control For Cross Site Requests."

Sachin Gaur
+2  A: 

The not very clear workaround (but works) is using iframe as container for requests to another sites. The problem is, the parent can not access iframe's content, can only navigate iframe's "src" attribut. But the iframe content can access parent's content.

So, if the iframe's content know, they can call some javascript content in parent page or directly access parent's DOM.

EDIT: Sample:

function ajaxWorkaroung() {
    var frm = gewtElementById("myIFrame")
    frm.src = "http://some_other_domain"
}
function ajaxCallback(parameter){
    // this function will be called from myIFrame's content
}
TcKs
IFrames are slower than ajax, and also in older IE I remember there is a 'click' sound played every iframe.src update :(
Thinker
In javascript one can not access the parent javascript data or functions cros-domain. The answer is untrue.
naugtur
@nagtur: I successfully used this scenario in some time ago :|.
TcKs
+2  A: 

The post marked as the answer is erroneous: the iframes document is NOT able to access the parent. The same origin policy works both ways.

The fact is that it is not possible in any way to consume a rest based webservice using xmlhttprequest. The only way to load data from a different domain (without any framework) is to use JSONP. Any other solutions demand a serverside proxy located on your own domain, or a client side proxy located on the remote domain and som sort of cross-site communication (like easyXDM) to communicate between the documents.

Sean Kinsey
-1 because this isn't inaccurate. It is possible to access the parent page from an IFRAME with JavaScript by using the 'parent' DOM object. For example this will modify an element in the page from within an IFRAME: parent.document.getElementById("someDiv").innerHTML = "some content";
Enrico Campidoglio
The question is about document from different domain - and the same origin policy will therefor be i effect. An IFrame from domainA is NOT able to access the contentDocument of its parent if the parent is from domainB.As the author of the easyXSS cross-site library, I do have some knowledge around this.
Sean Kinsey
I missunderstood your answer then. You are right, an iframe cannot access the parent page's content and viceversa when the two are being hosted in different domains. However in my case using an iframe works well, because it doesn't need to access the parent page in any way, but it simply posts an AJAX request to a service, which is hosted on its same domain.
Enrico Campidoglio
Do you mind fixing the rating for the answer then? :)
Sean Kinsey
You need to edit your answer, since SO won't allow me to change a vote that's too old
Enrico Campidoglio
easyXSS has been renamed to easyXDM, and it has also been improved quite a bit
Sean Kinsey