Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Fetch API to get flicker feed in json format

I manage to get json response from flicker feed api by using $.getJSON, but when i try to do it using Fetch i only seems to get an XML response.

This works:

var flickerAPI = "http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?";
$.getJSON(flickerAPI, {
                    tags: "searchTerm",
                    tagmode: "any",
                    format: "json"
                })
                .done(function (data) {
                   //....
                });

This does not work:

var flickerAPI = "http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?";

var request = new Request(flickerAPI, { 
                mode: 'no-cors',
                tags: 'searchTerm',
                tagmode: 'any',
                format: 'json'
            });

            fetch(request)
                .then(function (res) {
                    return res.json();
                })
                .then(function (text) {
                    console.log(text);
                });

I also would like to understand why when using the Fetch API i am getting: "No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled." and when using $.getJSON not. Thank you !!

like image 727
Amalin Avatar asked Mar 19 '17 10:03

Amalin


1 Answers

Short answer: the args for the fetch(…) method and behavior of the fetch(…) method are very different from the args for the $.getJSON(…) method and the behavior of the $.getJSON(…) method—so you can’t expect fetch(…) to do anything like what $.getJSON(…) does.

Longer answer, responding to your specific questions:

I also would like to understand why when using the Fetch API i am getting: "No 'Access-Control-Allow-Origin' header is present on the requested resource… and when using $.getJSON not.

Your request URL contains the substring callback=?, so $.getJSON handles it as JSONP:

If the URL includes the string "callback=?" (or similar, as defined by the server-side API), the request is treated as JSONP instead.

…which means that behind the scenes, instead of sending a cross-origin request from JavaScript, it instead creates a script element that loads the JSONP response. Since browsers allow the script element to be used to load scripts cross-origin, that never runs into any restrictions.

But when you make the call using the Fetch API, that doesn’t do any behind-the-scenes magic to automatically recognize the request as a JSONP request based on the URL, and doesn’t create a script element to load the response. Instead it just causes a request to get made directly to that http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?" URL.

But http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?" isn’t actually intended to be used with the Fetch API or XHR, so the response it sends back doesn’t include the Access-Control-Allow-Origin response header.

Per the CORS protocol, to a browser the lack of that Access-Control-Allow-Origin response header means “Don’t expose this response to any client-side JavaScript running in a web app”.

So your browser logs that “No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access” message to let you know your script won’t be able to access the response, and why.

If you’re setting mode: 'no-cors' I wouldn’t expect you’d be seeing that message. But you basically never want to set mode: 'no-cors' anyway, because doing so has the same effect as the lack of the Access-Control-Allow-Origin response header does—it prevents your script from having any access to the response at all.


As far as expecting tags: 'searchTerm', tagmode: 'any', and format: 'json' to have any effect if you specify them in the object you give as the second argument to the fetch(…) method, @Yazan’s comment above is right: those are custom query params for the flickr API, so if you’re doing a GET request with the Fetch API you need to specify them in the URL as query params.

$.getJSON, in contrast, does that for you automatically:

Data that is sent to the server is appended to the URL as a query string.

…where the data it means is the object of name/value pairs you give as the 2nd arg to $.getJSON.

In contrast, for the fetch(…) method, the names and values you specify in the second argument can’t be arbitrary query parameters. Instead only a predefined set of names are allowed there:

  • method: The request method, e.g., GET, POST.
  • headers: Any headers you want to add to your request
  • body: Any body that you want to add to your request
  • mode: The mode you want to use for the request
  • credentials: The request credentials you want to use for the request
  • cache: The cache mode you want to use for the request
  • redirect: The redirect mode to use
  • referrer: A USVString specifying no-referrer, client, or a URL
  • referrerPolicy: Specifies the value of the referer HTTP header
  • integrity: Contains the subresource integrity value of the request
like image 162
sideshowbarker Avatar answered Sep 28 '22 10:09

sideshowbarker