Wikipedia API + Cross-origin requests

时光怂恿深爱的人放手 提交于 2019-11-27 07:39:42

CORS headers are sent to ALLOW a requesting script to access the contents.

Wikipedia is sending the CORS, not YOU.

Update according to the comments:

Wikipedia as 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 docs:

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");
Ashton Morgan

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){ /* ... */ }
);

As of today, 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 at the MediaWiki API sandbox: MediaWiki API sandbox

You can use jQuery JSONP:

$.ajax( {
    url: "https://en.wikipedia.org/w/api.php",
    jsonp: "callback", 
    dataType: 'jsonp', 
    data: { 
        action: "query", 
        list: "search", 
        srsearch: "javascript", 
        format: "json" 
    },
    xhrFields: { withCredentials: true },
    success: function(response) { ... }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!