jQuery.getJSON - Access-Control-Allow-Origin Issue
Solution 1
It's simple, use $.getJSON()
function and in your URL just include
callback=?
as a parameter. That will convert the call to JSONP which is necessary to make cross-domain calls. More info: http://api.jquery.com/jQuery.getJSON/
Solution 2
You may well want to use JSON-P instead (see below). First a quick explanation.
The header you've mentioned is from the Cross Origin Resource Sharing standard. Beware that it is not supported by some browsers people actually use, and on other browsers (Microsoft's, sigh) it requires using a special object (XDomainRequest
) rather than the standard XMLHttpRequest
that jQuery uses. It also requires that you change server-side resources to explicitly allow the other origin (www.xxxx.com
).
To get the JSON data you're requesting, you basically have three options:
If possible, you can be maximally-compatible by correcting the location of the files you're loading so they have the same origin as the document you're loading them into. (I assume you must be loading them via Ajax, hence the Same Origin Policy issue showing up.)
-
Use JSON-P, which isn't subject to the SOP. jQuery has built-in support for it in its
ajax
call (just setdataType
to "jsonp" and jQuery will do all the client-side work). This requires server side changes, but not very big ones; basically whatever you have that's generating the JSON response just looks for a query string parameter called "callback" and wraps the JSON in JavaScript code that would call that function. E.g., if your current JSON response is:{"weather": "Dreary start but soon brightening into a fine summer day."}
Your script would look for the "callback" query string parameter (let's say that the parameter's value is "jsop123") and wraps that JSON in the syntax for a JavaScript function call:
jsonp123({"weather": "Dreary start but soon brightening into a fine summer day."});
That's it. JSON-P is very broadly compatible (because it works via JavaScript
script
tags). JSON-P is only forGET
, though, notPOST
(again because it works viascript
tags). -
Use CORS (the mechanism related to the header you quoted). Details in the specification linked above, but basically:
A. The browser will send your server a "preflight" message using the
OPTIONS
HTTP verb (method). It will contain the various headers it would send with theGET
orPOST
as well as the headers "Origin", "Access-Control-Request-Method" (e.g.,GET
orPOST
), and "Access-Control-Request-Headers" (the headers it wants to send).B. Your PHP decides, based on that information, whether the request is okay and if so responds with the "Access-Control-Allow-Origin", "Access-Control-Allow-Methods", and "Access-Control-Allow-Headers" headers with the values it will allow. You don't send any body (page) with that response.
C. The browser will look at your response and see whether it's allowed to send you the actual
GET
orPOST
. If so, it will send that request, again with the "Origin" and various "Access-Control-Request-xyz" headers.D. Your PHP examines those headers again to make sure they're still okay, and if so responds to the request.
In pseudo-code (I haven't done much PHP, so I'm not trying to do PHP syntax here):
// Find out what the request is asking for corsOrigin = get_request_header("Origin") corsMethod = get_request_header("Access-Control-Request-Method") corsHeaders = get_request_header("Access-Control-Request-Headers") if corsOrigin is null or "null" { // Requests from a `file://` path seem to come through without an // origin or with "null" (literally) as the origin. // In my case, for testing, I wanted to allow those and so I output // "*", but you may want to go another way. corsOrigin = "*" } // Decide whether to accept that request with those headers // If so: // Respond with headers saying what's allowed (here we're just echoing what they // asked for, except we may be using "*" [all] instead of the actual origin for // the "Access-Control-Allow-Origin" one) set_response_header("Access-Control-Allow-Origin", corsOrigin) set_response_header("Access-Control-Allow-Methods", corsMethod) set_response_header("Access-Control-Allow-Headers", corsHeaders) if the HTTP request method is "OPTIONS" { // Done, no body in response to OPTIONS stop } // Process the GET or POST here; output the body of the response
Again stressing that this is pseudo-code.
![Admin](/assets/logo_square_200-5d0d61d6853298bd2a4fe063103715b4daf2819fc21225efa21dfb93e61952ea.png)
Admin
Updated on June 03, 2020Comments
-
Admin about 4 years
I'm jusing jQuery's
$.getJSON()
function to return a short set of JSON data.I've got the JSON data sitting on a url such as
example.com
. I didn't realize it, but as I was accessing that same url, the JSON data couldn't be loaded. I followed through the console and found thatXMLHttpRequest
couldn't load due toAccess-Control-Allow-Origin
.Now, I've read through, a lot of sites that just said to use
$.getJSON()
and that would be the work around, but obviously it didn't work. Is there something I should change in the headers or in the function?Help is greatly appreciated.
-
Admin about 13 yearsIs there a way to do this utilizing jQuery? Or, is there a header I can set (via PHP) that will let this work?
-
T.J. Crowder about 13 years@Mike: Which "this"? If you mean JSON-P, yes, jQuery supports that in its
ajax
call; I've added some details above. If you mean CORS, then yes, that's headers you set via PHP in response to anOPTIONS
HTTP request and again in response to theGET
orPOST
; I've added some details for that as well. But it's all overkill if there's any chance you can just move the files so they're on the same origin. -
Simon almost 12 yearsThat depends entirely on the server accepting the extra callback parameter which it may not do in all cases.
-
chadpeppers over 10 yearsThis doesn't work 100% of the time as if the server is not set up to server jsonp then it still returns json, in which you will get an error.
-
Dinesh about 10 years@T.J.Crowder So $.getJSON does not work? do we need to use some other method like ajax and set the headers?
-
T.J. Crowder about 10 years@Dinesh:
$.getJSON
works fine provided either 1) It's a same-origin request, or 2) The browser and server both support CORS and the server allows the origin, or 3) The server provides a JSON-P interface and you tell jQuery you're using JSON-P by using?callback=
in the URL you give$.getJSON
. -
Dinesh about 10 years@T.J.Crowder Ok.. Could you please answer this question - stackoverflow.com/questions/22795561/…
-
smartmouse about 4 yearsIn my case I have CORS issue sometimes, not every time I open the site. So now I have applied this workaround but I cannot see if I have solved.
-
Nevada Stone about 3 years$.getJSON("api.github.com/users/jeresig?callback=?",function(json){ console.log(json); }); sitepoint.com/jsonp-examples