13

I'm trying to get a currency rate with the Google Currency Calculator using the following jquery (dummy) code:

    $.getJSON("http://www.google.com/ig/calculator?hl=en&q=1" + "DOP" + "=?" + "USD",
        function(data) {
            $('.currNumber').each(function (index) {
                $(this).html(parseFloat($(this).html()) * 0.02681);
                                  });
          });

XMLHttpRequest cannot load http://www.google.com/ig/calculator?hl=en&q=1DOP=?USD. Origin 'hostURL' is not allowed by Access-Control-Allow-Origin.

Looking in the site I've found various topics on the subject but they mostly refer to local file access and attempt to solve it by starting chrome with an additional parameter (I'm also using chrome) but such is not my issue, which actually seems more related to cross-domain restrictions.

So, question is: How can I use jQuery to get the rate from that url?

PedroC88
  • 3,440
  • 7
  • 40
  • 68
  • possible duplicate of [Cross domain scripting error?](http://stackoverflow.com/questions/1051748/cross-domain-scripting-error) – Joe Aug 27 '11 at 17:13

4 Answers4

17

Ajax requests are limited by the browser's Same Origin Policy. In a nutshell, that means that you can't talk directly to a server via ajax that isn't on the same domain as the page your script is running in. So, unless you're developing a page for google.com, you can't talk to google.com directly.

There are work-arounds for this limitation involving the insertion of script tags (JS files loaded via script tags are not subject to the same origin policy) and then using JSONP callbacks to communicate data results back to your main script from those script tags. That is probably what you need to do here if the API you're attempting to use supports it.

jQuery will help you a lot here as it can automatically turn an ajax call into a JSONP call that is loaded via script tags and can work in cross domain situations. According to the jQuery doc for it's ajax function, it will do this automatically if it sees "callback=" in the parameter string for the ajax call or if you set the crossDomain option.

jfriend00
  • 580,699
  • 78
  • 809
  • 825
  • 10
    I'm not a skilled web developer... How can this be accomplished? – PedroC88 Aug 27 '11 at 18:28
  • 1
    Please read my recent edits that describe it in more detail. jQuery can do most of the work for you, but you will have to configure the ajax call appropriately. – jfriend00 Aug 27 '11 at 18:30
  • I had already tried using `&callback=?` but that results in `resource interpreted as script but transferred with mime type text html` I take it that means that the response has a MIME type of text/html instead of text/javascript but I can't fix that since I don't have control over the response... can I? – PedroC88 Aug 27 '11 at 18:39
  • That's generally a harmless warning. If the resource was transferred as a script, then you should be OK. Did you point callback=xxxx to a javascript function of your own? Did you read about the JSONP support in that Google API and how it works? Some Googling on JSONP will probably help educate you and then studying the jQuery ajax doc as it relates to JSONP. – jfriend00 Aug 27 '11 at 18:41
  • jQuery's support for JSONP is only one side of the coin - jQuery can't work it's magic if the server/API doesn't support callbacks. – no.good.at.coding Aug 27 '11 at 19:21
  • Agree, the OP has to do the research to see if the API they are calling supports the callback parameter used by JSONP. I would expect any Google API meant for consumption in non-Google web pages to do since that's the main way it can be used, but the OP has to find out what is supported. – jfriend00 Aug 27 '11 at 19:23
  • @jfriend00 But I don't believe this service is meant for such a purpose - there is no public API and this is a hack using the URLs meant for iGoogle gadgets. Additionally, Google seems to be deprecating consumption of similar services via ajax. For example, the new Google Maps API doesn't support JSONP for geocoding; one must necessarily use the Google Maps JavaScript library. So unfortunately, I wouldn't count on JSONP in their APIs. – no.good.at.coding Aug 27 '11 at 19:36
  • If Google has a direct javascript API, then there's likely jSONP underneath - obviously better to use the javascript API (like with Facebook). If there's no JSONP, then this can't be used outside of a Google page because of same origin restrictions unless you build a server-proxy for it. – jfriend00 Aug 27 '11 at 19:59
  • *then there's likely jSONP underneath* - I don't think that holds. You could have a JS API without support for JSONP as is evident from the tons of APIs available already. – no.good.at.coding Aug 27 '11 at 21:47
  • Note: JSONP has security issues, and CORS is the new standard. – tschwab Jun 26 '17 at 16:45
  • @tschwab - The OP is trying to query some other service cross domain. The destination server apparently has not implemented CORS and the OP can't implement CORS for that server (since it isn't theirs) so JSONP would be their only choice for a purely client-side solution (if the server supports it). Otherwise, they'd have to find a 3rd-party proxy server (that did support CORS) to run the request through. In any case, this is a pretty old question (6 yrs old). – jfriend00 Jun 26 '17 at 21:40
2

It seems from this link - http://api.jquery.com/jQuery.ajax/ - which was provided earlier by jfriend00 - explains a parameter you can include in the JQuery ajax request called "crossDomain" which is a boolean.

crossDomain (default: false for same-domain requests, true for cross-domain requests) Type: Boolean If you wish to force a crossDomain request (such as JSONP) on the same domain, set the value of crossDomain to true. This allows, for example, server-side redirection to another domain. (version added: 1.5)

Therefore setting it to true should solve(?) this. I am not an expert, but I tried it after continuously running into this issue and it seemed to resolve the problem.

Example:

$.ajax({ //my ajax request
        url: "_URL_I_AM_MAKING_REQUEST_TO_",
        type: "GET",
        cache: false,
        dataType: "json",
        **crossDomain: true,**
        data: { _mydata_
        success : function(response){}
});
Adam
  • 192
  • 1
  • 2
  • 14
  • 1
    That is not what the property is for. If you read what it says in the jQuery documentation it 'If you wish to force a crossDomain request (such as JSONP) on the same domain, set the value of crossDomain to true.' it states that it will make same domain requests look like cross domain ones. – Ian Jul 10 '13 at 08:08
2

Edit
I thought it was clear what the problem was but it seems it might not be so here goes. This error you're seeing is the server restricting your domain from accessing it's resources via ajax requests. This is standard JavaScript security - your script can only talk to the domain it originated from. Since your JavaScript was not loaded from Google's domains, it's not in the list of domains allowed to access the calculator API via ajax and that's why you see this error message.

Options for making cross domain requests with jQuery are outlined here. As I mentioned earlier, JSONP will only be a valid option if the server supports it because it must send back appropriately formatted JSON.


It might help if you provided links to the pages that you're referring to.

From the looks of things though, this API doesn't support JSONP (unless there is an undocumented parameter) which is pretty much your only option for cross-domain ajax requests in this case since you don't control the server and can't change the access control headers.

You might want to consider building a server-side resource that will access this API for you without being constrained by the JavaScript security model such as the PHP script here.

no.good.at.coding
  • 19,647
  • 1
  • 57
  • 51
  • Link to which pages? The one with the JSON response? That is `http://www.google.com/ig/calculator?hl=en&q=1DOP=?USD` I'm also developing this for webworks (so this won't run on any server but in a mobile instead) – PedroC88 Aug 27 '11 at 18:10
  • @PedroC88 Is there documentation on the API? You say you've found various topics on the subject; where? – no.good.at.coding Aug 27 '11 at 19:18
  • Various topics on the error of the browser, not on the API perse, actually, 'bout that API I haven't found squad. – PedroC88 Aug 27 '11 at 21:26
  • Ah, I see - I thought you meant you'd seen documentation for the API. Well, there seems to be no evidence of support for JSONP without which you can't use this service via ajax, unfortunately. Consider a writing a simple PHP proxy. If you're hosting your own Apache server, you could also use a proxy/reverse proxy to transparently redirect requests outside of your domain. – no.good.at.coding Aug 27 '11 at 21:49
1

Minor additional point of info.

I got to this question because I got this error trying to post to my own server.

Solution: make sure hostname matches in ajax call.

Exmaple:

//This failed

$.post("http://domain.com/index.php/count/",

//This succeeded (the page this was called from was www.domain.com/.....)

$.post("http://www.domain.com/index.php/count/",
ssaltman
  • 3,323
  • 1
  • 16
  • 21