rsturim
rsturim

Reputation: 6846

How do I make an Cross Domain Request with Ajax?

I've been asked to get some "data" from an xml feed and to add it to a page I am hosting on my server. I figured I'd use the jQuery Ajax api -- and I'm getting this error.

XMLHttpRequest cannot load .../3.atom. Origin http://myserver.com is not allowed by Access-Control-Allow-Origin.

Do I need to request access from someone? Is there something I can add to my request? I've read stuff about CORS, is that a service I should use in this case?

Here's my code at the moment.

var feedUrl = "http://www.holmanreviews.com/audi-pembroke-pines/3.atom";
var content;

$.ajax({
    type: "GET",
    url: feedUrl,
    dataType: "xml",
    crossDomain: true,
    success: function (xml) {
        $(xml).find('entry').each(function () {
            var $this = $(this);
            var id = $this.attr('id');
            content += id;
        });
    }
});

$('#feed').append(content);

I have a JS FIddle here as well. http://jsfiddle.net/rsturim/6nsyX/

Would love some background on this if you can help -- thanks a bunch.

Upvotes: 0

Views: 1750

Answers (3)

hippietrail
hippietrail

Reputation: 16974

You were making the request correctly but the remote site would need to support CORS and the error you're receiving means it does not support it.

Since it's an Atom feed, there's probably not much chance the remote site supports JSONP so your best approach is to use a proxy. And instead of rolling your own you can use Yahoo's YQL to fetch either XML or JSON. YQL does support CORS so you can get either.

XML:

http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20url%3D%22http%3A%2F%2Fwww.holmanreviews.com%2Faudi-pembroke-pines%2F3.atom%22%20and%20itemPath%3D%22feed.entry%22&format=xml

JSON:

http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20url%3D%22http%3A%2F%2Fwww.holmanreviews.com%2Faudi-pembroke-pines%2F3.atom%22%20and%20itemPath%3D%22feed.entry%22&format=json

XML will give you exactly what you would've got from the site directly, but it's not much fun to parse XML with JavaScript, so I highly recommend using the JSON. (You could also get JSONP but JSON with CORS support is better.)

From your code I'm pretty sure you're capable of building these URLs from the basic URL so I'll leave that as an exercise (-;


Oh if you really need to support Internet Explorer versions earlier than 10, or any other browser that doesn't support CORS, here's a neat way to use CORS when the browser supports it and JSONP otherwise:

dataType: $.support.cors ? "json" : "jsonp"

Upvotes: 1

monsur
monsur

Reputation: 47927

You are probably going to need to set up a server-side proxy in order to access this data.

CORS won't work because you are not in control of the server.

JSON-P won't work because the server doesn't seem to accept a "callback" parameter. I tested this by appending "?callback=foo" to your request url, which did not change the response. It is possible that their API supports some other name for the callback parameter, but its hard to know without seeing any documentation for their API.

Upvotes: 2

Sebastian vom Meer
Sebastian vom Meer

Reputation: 5241

You have to use JSONP for this. It's a nice trick to break same origin policies. It is very dangerous, so you have to trust the data's provider.

Use the related dataType in your request config:

dataType: "xml"

Additionally, your feed needs to support JSONP. This means, if the request URL is suffixed by a query like callback=?, the response must be wrapped in a Javascript function and quotes need to be esacaped:

callback("<your-xml>...</your-xml>");

This is the basic idea of JSONP. If you want to understand why you have to it this way just have look at the Wikipedia article for examle: JSONP

Upvotes: 0

Related Questions