Pierre Pierre - 4 months ago 16
Javascript Question

Wikipedia API + Cross-origin requests

I'm trying to access wikipedia using javascript+CORS

As far as I know, wikipedia should support CORS: http://www.mediawiki.org/wiki/API:Cross-site_requests

I tried the following script: create a XMLHttpRequest+credential/XDomainRequest, add some Http-Headers ( "Access-Control-Allow-Credentials",...) and send the query.

http://jsfiddle.net/lindenb/Vr7RS/

var WikipediaCORS=
{
setMessage:function(msg)
{
var span=document.getElementById("id1");
span.appendChild(document.createTextNode(msg));
},
// Create the XHR object.
createCORSRequest:function(url)
{
var xhr = new XMLHttpRequest();


if ("withCredentials" in xhr)
{
xhr.open("GET", url, true);
}
else if (typeof XDomainRequest != "undefined")
{
xhr = new XDomainRequest();
xhr.open(method, url);
}
else
{
return null;
}
xhr.setRequestHeader("Access-Control-Allow-Credentials", "true");
xhr.setRequestHeader("Access-Control-Allow-Origin","*");
return xhr;
},
init:function()
{
var _this=this;
var url = 'http://en.wikipedia.org/w/api.php?action=opensearch&search=Javascript&format=json';
var xhr = this.createCORSRequest(url);
if (!xhr)
{
this.setMessage('CORS not supported');
return;
}

xhr.onload = function()
{
_this.setMessage(xhr.responseText);
};
xhr.onerror = function()
{
_this.setMessage('Woops, there was an error making the request.');
};
xhr.send();
}
};


But my script fails ('xhr.onerror' is called). How can I fix it ?

Thanks.

Answer

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

Wikipedia is sending the CORS, not YOU.

From the page you linked:

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 a 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");