Cross-site AJAX requests

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

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

The problem is that I have no control over the domain nor the web server where the site is hosted. This means that 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 I have this work in other browsers beside Internet Explorer?

Answers:

Answer

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

Answer

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.

Answer

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.

Answer

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

Make your service domain accept cross origin resource sharing (CORS).

Typical scenario: Most CORS compliant browsers will first send an OPTIONS header, to which, the server should return information about which headers are accepted. If the headers satisfy the service's requirements for the request provided (Allowed Methods being GET and POST, Allowed-Origin *, etc), the browser will then resend the request with the appropriate method (GET, POST, etc.).

Everything this point forward is the same as when you are using IE, or more simply, if you were posting to the same domain.

Caviots: Some service development SDK's (WCF in particular) will attempt to process the request, in which case you need to preprocess the OPTIONS Method to respond to the request and avoid the method being called twice on the server.

In short, the problem lies server-side.

Edit There is one issue with IE 9 and below with CORS, in that it is not fully implemented. Luckily, you can solve this problem by making your calls from server-side code to the service and have it come back through your server (e.g. mypage.aspx?service=blah&method=blahblah&p0=firstParam=something). From here, your server side code should implement a request/response stream model.

Answer

Just use a server side proxy on your origin domain. Here is an example: http://jquery-howto.blogspot.com/2009/04/cross-domain-ajax-querying-with-jquery.html

Answer

This can also be done using a webserver setup localy that calls curl with the correct arguments and returns the curl output.

app.rb

require 'sinatra'
require 'curb'

set :views,lambda {"views/"+self.name.to_s.downcase.sub("controller","")}
set :haml, :layout => :'../layout', :format => :html5, :escape_html=>true
disable :raise_errors

get '/data/:brand' do
  data_link =  "https://externalsite.com/#{params[:brand]}"
  c = Curl::Easy.perform(data_link)
  c.body_str
end

Sending an ajax request to localhost:4567/data/something will return the result from externalsite.com/something.

Answer

Another option would be to setup a CNAME record on your own domain to "Mask" the remote domain hostname.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us Javascript

©2020 All rights reserved.