Wikipedia API + Cross-origin requests
I had the same problem while working on a freeCodeCamp project and the solution was so simple it made me laugh, since I had spent hours searching for it. In your jQuery URL include the parameter below.
&origin=*
Working CodePen
$.getJSON(
'https://en.wikipedia.org/w/api.php?action=query&format=json&gsrlimit=15&generator=search' +
'&origin=*' + // <-- this is the magic ingredient!
'&gsrsearch='q, function(data){ /* ... */ }
);
CORS headers are sent to allow a requesting script to access the contents.
Wikipedia is sending the CORS, not you.
According to the comments:
Wikipedia is an exception to general rule, by requiring you to append an origin
parameter to the URL you are requesting.
I think the reason behind this is related to caching. I don't know what kind of mechanism they are using, but it probably makes it easier and better for them to store a cache object and build variations that way.
More on CORS from MediaWiki API documentation:
The MediaWiki API also requires that the origin be supplied as a request parameter, appropriately named "origin", which is matched against the Origin header required by the CORS protocol. Note that this header must be included in any pre-flight request, and so should be included in the query string portion of the request URI even for POST requests.
If the CORS origin check passes, MediaWiki will include the Access-Control-Allow-Credentials: true header in the response, so authentication cookies may be sent.
This means you have to send an Origin
header to tell Wikipedia where you are coming from. Wikipedia is managing the access, not you.
Send this origin header:
xhr.setRequestHeader("Origin", "http://www.yourpage.com");
Access-Control-Allow-*
headers are response headers, not request headers.
Wikipedia additionally requires content type json:
xhr.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
As of August 2016, Wikipedia supports CORS requests by using the normal Ajax requests (no need of JSONP/callback manipulation). This can be done by setting the origin in the API call.
For authenticated requests, this must match the one of the one of the "origins" in the Origin header exactly (you need to set this using the beforeSend property while making an Ajax call).
For unauthenticated requests, you can simply set it as an asterisk (*), and it works when using a simple $.getJSON from your domain.
Example API call: https://en.wikipedia.org//w/api.php?action=opensearch&format=json&origin=*&search=stack&limit=10
More is at the MediaWiki API sandbox: MediaWiki API sandbox