3

I am trying to search images on Wikimedia Commons, using MediaWiki API. Here is my requested URL with search params:

https://commons.wikimedia.org/w/api.php?action=query&list=allimages&format=json&aifrom=Dada

I am succeed to get response in JSON format, but I could not read it programmatically because:

No 'Access-Control-Allow-Origin' header is present on the requested resource.

Any advice?

UPDATE:

I have added one more param to the url: callback=JSON_CALLBACK, which transforms response to jsonp format. Now it possible to use angular $http.jsonp() method also.

Damjan Pavlica
  • 31,277
  • 10
  • 71
  • 76

2 Answers2

3

use jsonp1 as dataType to prevent the "No 'Access-Control-Allow-Origin' header is present on the requested resource." error. Then it works :

$.ajax({
    dataType: 'jsonp',
    url : 'https://commons.wikimedia.org/w/api.php?action=query&list=allimages&format=json&aifrom=Dada',
    success : function(json) {
        json.query.allimages.forEach(function(item) {
            $('<img/>', { src : item.url }).appendTo('#images');
        })    
    }     
})    

Here I add each image to a #images <div> just for demonstration purposes.

demo -> http://jsfiddle.net/52g2Lazw/

1) JSONP stands for “JSON with Padding” and it is a workaround for loading data from different domains. It loads the script into the head of the DOM and thus you can access the information as if it were loaded on your own domain, thus by-passing the cross domain issue cite.

davidkonrad
  • 83,997
  • 17
  • 205
  • 265
1

If you are accessing the Wikimedia Commons API from a Wikimedia wiki, you can use the origin parameter of the API and this way make the API setting CORS headers. E.g. on en.wikipedia.org, you could access the Commons API this way:

$.get('https://commons.wikimedia.org/w/api.php?' +
    $.param({
        format: 'json',
        action: 'query',
        list: 'allimages',
        aifrom: 'Dada',
        origin: location.protocol + '//' + location.host
    })).done(function() { /*...*/ });

It is generally safer to use JSON (a pure data format) than loading and executing JavaScript (JSONP) file that could, in theory, do evil with your visitors. I would probably set up a proxy server for this purpose, instead of using JSONP. A simple web search for set up a proxy json may result in plenty of useful results.

Rainer Rillke
  • 1,281
  • 12
  • 24
  • what about if you wanted to access the MediaWiki search API using plain javscript? – Brian Zelip Apr 29 '16 at 14:09
  • 1
    @BrianZ: In Browsers one would use [an XHR](https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest) and [`JSON.parse()`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse). – Rainer Rillke Apr 30 '16 at 15:06
  • I've got a working example of XHR and `JSON.parse()` here -- http://jsbin.com/gilunipiwe/edit?html,js,output . If you open your browser console you'll see that the example gets the response at the network level but suffers from "Cross-Origin Request Blocked". How can I get past this Cross-origin block in the jsbin example here? – Brian Zelip May 03 '16 at 11:42
  • 1
    @BrianZ One would have to set up a proxy that doesn't care about origins and itself sets a Cross-Origin header that would allow script from jsbin to read the response when not running the code from a Wikimedia wiki. – Rainer Rillke May 04 '16 at 08:33