XMLHttpRequest - flickr - cross origin header - javascript

just having a play with the Flickr API and seem to be unable to successfully claw anything out of it.
I tried using Jquery code below
var flickrURL = "https://api.flickr.com/services/feeds/photos_public.gne?format=jsoncallback=?";
var flickrOptions = {
tags: "cats",
format: "json"
}
var ajaxCallback = function(data){
console.log(data);
};
$.getJSON(flickrURL, flickrOptions, ajaxCallback);
I also tried the old vanilla route
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.flickr.com/services/feeds/photos_public.gne?format=jsoncallback=?");
xhr.onreadystatechange = function(data){
console.log(data);
}
xhr.send();
I have used AJAX/XMLrequest successful but not with an API. The when the vanilla fails I'm getting 'No 'Access-Control-Allow-Origin' header' which I don't understand since it's meant to be an open feed and with the Jquery I'm getting 'jsonFlickrFeed is not defined'. Both of which I find very puzzling

Sumeets answer is correct but just thought I'd post my vanilla solution off the back of that.
var script = document.createElement('script');
script.src = "https://api.flickr.com/services/feeds/photos_public.gne?format=json";
document.getElementsByTagName('head')[0].appendChild(script);
var jsonFlickrFeed = function(data){
console.log(data);
}

You just have to do minor changes
var flickrURL =
"https://api.flickr.com/services/feeds/photos_public.gne?format=jsoncallback=?";
var flickrOptions = {
tags: "cats",
format: "json"
}
var jsonFlickrFeed = function(data){
console.log(data);
};
$.getJSON(flickrURL, flickrOptions);
Flickr response looks for jsonFlickrFeed function which was not defined in your case.
https://codepen.io/smtgohil/pen/ZXeYqB?editors=0010
You can check the console for output.

Related

How to get response value from fetch instead of a promise with no value?

I am building a chrome extension to pull data out of a page to build a url from the data and I want to have that url shortened as the final product. In my content scripts file I make a call out to a url shortener to compress a link. I keep getting returned a promise with no value which crashes react. In devtools I see that the callout is made successfully and the url is returned.
I have tried async await, a full async function, tried forcing the response.toString()
Here is the relevant section of code.
var listingInfo = new Map();
listingInfo.set('Address', 'some standard address');
var tinyLink = '(http://tinyurl.com)/api-create.php?url='; //() because I can't share shortener urls on this site.
/*-----------------------------------GET LINKS--------------------------*/
if(listingInfo.has('Address')){ var mapsLink = \`https://www.google.com/maps/place/${listingInfo.get('Address').replace(new RegExp(" ", "g"), '+')}\`;
tinyLink = \`${tinyLink}${mapsLink} `;
var dirLink = fetch(tinyLink, {
method: "GET",
mode: "no-cors",
headers: {"Content-Type": "text/html"} }).then((response)=>{
return response; });
listingInfo.set('dirLink', dirLink); }
I expected to receive a plain text string because in the network tab of devtools it shows a simple string url and not any JSON, but I keep receiving a resolved promise with value="".
// made this function to use XMLHttpRequest()
const setLink = (propName, url) => {
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
var link = xhr.responseText;
console.log(`link: '${link}'`);
listingInfo.set(propName, link);
}
}
xhr.send();
}
// Then called setLink()
if(listingInfo.has('Address')){
var mapsLink =
`https://www.google.com/maps/place/${listingInfo.get('Address').replace(new
RegExp(" ", "g"), '+')}`;
dirLink = `${tinyLink}${mapsLink}`;
console.log(dirLink);
setLink('dirLink', dirLink);
console.log(dirLink);
}

How to have javascript read a JSON URL

I want my javascript file to search a URL that is a JSON and grab specific contents from the page. This is the URL
And I want to grab the averageratingscore_rf.
I've even tried this :
var getJSON = function(url, callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'json';
xhr.onload = function() {
var status = xhr.status;
if (status === 200) {
callback(null, xhr.response);
} else {
callback(status, xhr.response);
}
};
xhr.send();
};
getJSON('https://search.mtvnservices.com/typeahead/suggest/?solrformat=true&rows=20&callback=noCB&q=burgos+AND+schoolid_s%3A1262&defType=edismax&qf=teacherfirstname_t%5E2000+teacherlastname_t%5E2000+teacherfullname_t%5E2000+autosuggest&bf=pow(total_number_of_ratings_i%2C2.1)&sort=total_number_of_ratings_i+desc&siteName=rmp&rows=20&start=0&fl=pk_id+teacherfirstname_t+teacherlastname_t+total_number_of_ratings_i+averageratingscore_rf+schoolid_s&fq=',
function(err, data) {
if (err !== null) {
alert('Something went wrong: ' + err);
} else {
console.log(data.response.docs.averageratingscore_rf);
}
});
But this doesn't work.
It's not a json, it's jsonp response.
JSONP requests perfomed by pass callback name and load this url into DOM script tag.
just don't try ajax+eval, anyway CORS restricts ajax here
Also, data.response.docs is an array, you should iterate it to access averageratingscore_rf
let cb = 'mycallback';
let url = `https://search.mtvnservices.com/typeahead/suggest/?solrformat=true&rows=20&callback=${cb}&q=burgos+AND+schoolid_s%3A1262&defType=edismax&qf=teacherfirstname_t%5E2000+teacherlastname_t%5E2000+teacherfullname_t%5E2000+autosuggest&bf=pow(total_number_of_ratings_i%2C2.1)&sort=total_number_of_ratings_i+desc&siteName=rmp&rows=20&start=0&fl=pk_id+teacherfirstname_t+teacherlastname_t+total_number_of_ratings_i+averageratingscore_rf+schoolid_s&fq=`
function mycallback(data) {
let res = data.response.docs.map(doc => doc.averageratingscore_rf)
console.log('averageratingscore_rf of docs:', res);
}
let script = document.createElement('script');
script.src = url;
document.body.appendChild(script)
Your URL is for JSONP, removing the callback argument returns JSON. (Remove callback=noCB)
Since you tagged google-chrome-extension Same Origin Policy may not apply but keep in mind Cross Origin Resource Sharing may need to be enabled.
... or you could handle the JSONP
Your URL isn't giving back pure JSON. There's a noCB() function wrapping it. That's probably why it's not being read.
Here's what I saw when I opened the URL:
noCB({ "responseHeader":{ "status":0, "QTime":1}, "response":{"numFound":1,"start":0,"docs":[ { "teacherlastname_t":"Burgos", "pk_id":282380, "schoolid_s":"1262", "averageratingscore_rf":2.47, "total_number_of_ratings_i":125, "teacherfirstname_t":"Fernando"}] }, "spellcheck":{ "suggestions":[]}} );
You may be able to execute that method, but if you only want the json, you can either strip out the "noCB(" and ");" at the beginning or the end when you get it, or strip it out at the server.

Make an API call from JavaScript

I'm attempting to make a call to an API, which takes requests in the form of Mongodb's '.find' method.
Using postman I can make the following call and I get the correct response.
http://asterank.com/api/asterank?query={"full_name": {"$eq" : "(2004 EU22)"}}&limit=5
But, when I try to make the same call in JavaScript, my entire web application just shows a blank webpage. So is the following way of utilizing a mongodb call wrong?
var example = "0";
function getAsterank(){
//ARRAY OF NEO NAMES
var xhr = new XMLHttpRequest();
xhr.open("GET", 'http://asterank.com/api/asterank?query={"full_name": {"$eq" : "(2004 EU22)"}}&limit=5', false);
xhr.send(null)
responseData = JSON.parse(xhr.response);
xhr.abort();
example = responseData;
}
If I make this same exact JS call using a different api such as the following, it works just fine. I use sublime text so I don't think I can debug it to see whats actually happening.
v
ar MeMe = "0";
function getAsterank(){
//ARRAY OF NEO NAMES
var xhr = new XMLHttpRequest();
xhr.open("GET", 'https://api.nasa.gov/neo/rest/v1/feed/today?detailed=true&api_key=NnRe38qGPTpKPtsenpkqROMTtXvkWnVNyql9lmnP', false);
xhr.send(null)
responseData = JSON.parse(xhr.response);
xhr.abort();
MeMe = responseData;
}
if jquery is an option this might be a solution
$(document).ready(function(){
$(".submitBottom").click( function() {
$.ajax({
type: "GET",
url: 'http://asterank.com/api/asterank?query={"full_name":{"$eq":"(2004 EU22)"}}&limit=5',
encode: true,
success: function (data) {
console.log("success", data)
}
});
});
});

How to parse data from this api and display it in my html?

I am brand new to javascript and have spent the past few hours trying to parse json data from an api url into my body in my html document. My only experience with APIs are with C# wrappers so this is new to me.
This is the API url: https://catfact.ninja/fact
I'm not sure where to go from here. I've been able to successfully pull the data I want, but I'm only able to print it to the console and I'm not sure how to pull that data into html. Here is my javascript code:
var HttpClient = function() {
this.get = function(aUrl, aCallback) {
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
var anHttpRequest = new XMLHttpRequest();
anHttpRequest.onreadystatechange = function() {
if (anHttpRequest.readyState == 4 && anHttpRequest.status == 200)
aCallback(anHttpRequest.responseText);
}
anHttpRequest.open( "GET", aUrl, true );
anHttpRequest.send( null );
}
}
var client = new HttpClient();
client.get('https://catfact.ninja/fact', function(response) {
var vsplit = response.split("\"")
console.log(vsplit[3]);
$('body').html(document.write(vsplit[3]));
});
Thanks for any help, sorry if I seem dumb
The first issue you have is that the call to document.write in the html function will not produce the results you think. document.write is a synchronous write function that tries to inject a string into the DOM renderer at the point it's called. If you remove that, you should have more luck seeing something in the HTML, but you can also use the following.
The response from https://catfact.ninja/fact is the following.
{"fact":"Cats' eyes shine in the dark because of the tapetum, a reflective layer in the eye, which acts like a mirror.","length":109}
There's no need to split the response when the format is JSON. You can use JSON.parse to create a Javascript Object. For example.
// data will contain data.fact, and data.length
var data = JSON.parse(response);
// Without using jQuery, you can set the html of the body directly
var body = document.getElementsByTagName("body")[0];
body.innerHTML = data.fact;

Backbone.js won't make cross-host requests?

I've been playing with Backbone in my Chrome console and running into a cross-domain problem that I can't figure out.
The host I'm connecting to presumably correctly implements CORS because a raw XHR request returns the expected JSON:
var http = new XMLHttpRequest();
http.open('GET', 'http://example.com:3000/entities/item/15.json', true);
http.onreadystatechange = function(evt) { console.log(evt); }
http.send();
(logs 3 XHR progress events on the console with the correct data in the response)
But when I do the following with Backbone the browser doesn't like it:
var Item = Backbone.Model.extend({});
var ItemsCollection = Backbone.Collection.extend({
model: Item,
url: 'http://example.com:3000/entities/item/'
});
var items = new ItemsCollection();
items.fetch();
(returns XMLHttpRequest cannot load http://example.com:3000/entities/item/. Origin http://localhost:8000 is not allowed by Access-Control-Allow-Origin.)
Is there anything I need to do to tell Backbone to work with CORS? This error seems to have come before the browser even made a request, so I don't think it's a server config error.
I hope one of these helps (I didn't try yet):
1. Overriding Backbone.js sync to allow Cross Origin
(function() {
var proxiedSync = Backbone.sync;
Backbone.sync = function(method, model, options) {
options || (options = {});
if (!options.crossDomain) {
options.crossDomain = true;
}
if (!options.xhrFields) {
options.xhrFields = {withCredentials:true};
}
return proxiedSync(method, model, options);
};
})();
2. Cross domain CORS support for backbone.js
$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
options.crossDomain ={
crossDomain: true
};
options.xhrFields = {
withCredentials: true
};
});
hey you can use something like:
var PostsCollection = Backbone.Collection.extend({
initialize: function(models, options) {
//this.id = options.id;
},
url: 'http://myapi/api/get_posts/?count=8',
});
posts = new PostsCollection();
posts.fetch({
dataType: 'jsonp',
success : function (data) {
console.log(data);
}
});
the key is we need to use 'jsonp'
It turns out the URLs I was requesting with Backbone were slightly different than those requested via the XHR (they were missing a queryarg). This caused the server to 500, which doesn't have the CORS headers. Chrome didn't show the HTTP request at all in the network tab of the debug panel, so I was extremely confused.
Fixing the 500 on the server made this work again.

Categories

Resources