Javascript : Fetch api vs AJAX - javascript

I have this code
fetch('http://example.com/movies.json')
.then(response => response.json())
.then(data => console.log(data));
Is using Fetch API for a request like in the code above considered as an AJAX request?
I a request considered an AJAX request only if we use the XMLHttpRequest object ?

Yes, There are several ways to send Asynchronous requests like jQuery, axios, Fetch API or XMLhttprequest.

fetch is an ajax request.
but fetch is a simple api and have not, so I recommended fatcher
fatcher is a lightweight HTTP request library based on fetch, allows us to use native fetch for web requests in a browser and NodeJS environment.
It is wrapped using the native fetch, we require that browsers or NodeJS support fetch when we use it.
Fetch support is already pretty good in modern browsers, so we don't have to worry about FETCH compatibility
In NodeJS, fetch already has some support starting with '18.0.0'
Fatcher aims to embrace the fetch of the standard library and at the same time provide some functions that cannot be provided in fetch, as well as make the function better expand and reuse.
import { fatcher, isFatcherError } from 'fatcher';
fatcher({
url: '/',
})
.then(result => {
// Response
const { data, status } = result;
})
.catch(err => {
// Catch Fatcher Error
if (isFatcherError(err)) {
// Request successfully. But response status code is not 2xx.
console.error(err.toJSON());
return;
}
// This is other errors.
});

Related

API fetch from PVGIS with javascript/Node.js

I'm in pursue of solution how to fetch data from API "PVGIS" (https://re.jrc.ec.europa.eu/api/) using vanilla javascript and process data for futher calcualtions
when accessing api from browser js script i get an "CORS policy error"
when accessing API from standalone node.js script i can fetch a data
here is fetch function from node that outputs data correctly
async function fetchData() {
const data = await fetch('https://re.jrc.ec.europa.eu/api/PVcalc?lat=45&lon=8&peakpower=1&loss=14&outputformat=json')
.then(response => response.json())
.then(json => {
console.log(json.outputs.monthly)
})
}
as i understand, i should be building a backend server side with api request to pvgis and then connecting it with my front js side to process the data ... is this a correct path?
Can you give me some details how to get going ?
here is the GUI of this api
https://re.jrc.ec.europa.eu/pvg_tools/en/tools.html
and API documentation
https://joint-research-centre.ec.europa.eu/pvgis-online-tool/getting-started-pvgis/api-non-interactive-service_en
As the website says, they are not making this API's available for use in browser
Warning: access to PVGIS APIs via AJAX is not allowed. Please, do not ask for changes in our CORS policy since these requests will be rejected by the system administrators.
They basically have CORS policy which blocks any other origin to make request. Cors is basically browser security mechanism. But as you mentioned you can access it through script since its not in browser.
Also as they mentioned, they have rate limiters so you can not call api every second.
Way to go here would be to have backend script on nodeJS which calls api, gets data and saves it in your database and then you would have another api endpoint, that queries this data from database. Also add some cron job, which would schedule request to get newer data from api every hour or so, so your db data does not go stale

How can I turn a Node.js http.IncomingMessage into a Fetch Request object?

I'm trying to work with the eBay APIs. It's a small personal project that just needs to run locally, and although I know C#, I'm much more comfortable with Javascript so I'm looking for ways to get this done in JS.
I found this promising looking eBay Node API with browser support. Browser support is something I'm looking for, but it also says that
A Proxy server is required to use the API in the Browser.
They give an example file for a proxy server that is a Cloudflare worker.
I'm trying to translate that into something I can run in Node locally using the basic Node HTTP server. I've been following through it and am doing OK so far, figured out the different ways to access the headers and check them, etc., but now I'm at the point where the proxy server is making the proxy request to the eBay APIs. The way the example file is set up, it seems as though the Cloudflare worker intercepts the HTTP request and by default treats it as a Fetch Request. So then when it goes to pass on the request, it just kind of clones it (but is replacing the headers with "cleaned" headers):
// "recHeaders" is an object that is _most_ of the original
// request headers, with a few cleaned out, and "fetchUrl"
// is the true intended URL to query at eBay
const newReq = new Request(event.request, {
"headers": recHeaders
});
const response = await fetch(encodeURI(fetchUrl), newReq);
The problem is that I don't have a Fetch Request to clone - since I'm running a Node HTTP server, what is event.request in the example code is for me a http.IncomingMessage.
So how can I turn that into a Fetch Request? I'm guessing at the very least there's stuff in the message body that needs to get passed along, if not other properties I'm not even aware of...
I don't mind doing the work, i.e. reading the stream to pull out the body, and then putting that into the Request object somehow (or do I even need to do that? Can I just pipe the stream from the IncomingMessage directly into a Request somehow?), but what else besides the body do I need to make sure I get from the IncomingMessage to put into the Request?
How do I turn a Node http.IncomingMessage into a Fetch Request and be sure to include all relevant parts?
I've made a simple function to convert.
const convertIncomingMessageToRequest = (req: ExpressRequest): Request => {
var headers = new Headers();
for (var key in req.headers) {
if (req.headers[key]) headers.append(key, req.headers[key] as string);
}
let request = new Request(req.url, {
method: req.method,
body: req.method === 'POST' ? req.body : null,
headers,
})
return request
}

JS equivalent of Python request

I am requesting a response from Spotify API. All I need to know is how to get this python script statement into js. What should I use in java that is like requests in python
query = "https://api.spotify.com/v1/playlists/{}/tracks?uris=.
{}".format(created_playlist, tracks);
response = requests.post(query, {"headers": {"Content-Type": "application/json", "Authorization": "Bearer {}".format(token3)}})
For Javascript, ES6+, use the native fetch API to perform REST HTTP requests,
alternative is the npm axios library, check its documentation
you can use the fetch API its a promise based function different from python requests module
fetch('http://example.com/movies.json')
.then(response => response.json())
.then(data => console.log(data));
here are the docs
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

ES6: Retrieve response headers from a CORS fetch call

I have a react application using ES6 fetch API to call a rest endpoint using CORS. The fetch call work just fine, but I'm unable to get the response headers that are being sent from the server. I can see the response headers in Chromes devtools so I know they are being sent back to me; however access to them in code doesn't seem to work for me. Here is the code (its basic fetch promise-chaining):
fetch(url)
.then(response => {
for (let header of response.headers) { < -- - headers is empty
console.log(header);
}
return response;
});
But response.headers is empty. But I can clearly see the headers in Chrome. Is there a reason why the fetch call is blocking me from viewing them? What do I need to get access to these headers? The server stores some application specific headers that we would love to use.
UPDATE: I was able to fix this by having the server add this to the response of the OPTION request:
response.setHeader("Access-Control-Expose-Headers", "X-Custom-Header");
Now on the response of the fetch command, I can do the following:
const customHeader = response.headers.get('X-Custom-Header');
Thank you Karim for the help on this!
To get a specific header you need to call response.headers.get(key)
and the iterable object is response.headers.entries and not response.headers
for (let header of response.headers.entries()) {
console.log(header);
}
https://developer.mozilla.org/en-US/docs/Web/API/Headers/entries
In addition, in a cors scenario only some headers are exposed to the app, thus not all the headers you see on the chrome dev tools are necessarily available at application level.
For further details check this answer:
Reading response headers with Fetch API

Why doesn't d3.json send cookies with the request?

I'm new to doing ajax requests with the built-in methods in d3.js (v5). Here's my code:
d3.json(uri).then(data =>console.log(data));
I tried this in an app that uses cookie authentication, and kept getting 401 status codes. Using the chrome dev tools revealed that it's sending the request without any cookies at all.
That's weird because ajax requests in native javascript send cookies along with every request by default. Here's an example of an ajax request in native javascript:
function nativeAjax(uri, callback) {
let request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (request.readyState === 4) {
callback(request);
}
}
request.open('get', uri, true);
request.send(null);
}
nativeAjax(uri, request => console.log(request.status));
Plugging this into my app, chrome dev tools shows it does send the authentication cookie along with the request and indeed the request.status comes back as 200 showing that it is indeed authenticated.
My questions are:
how can I configure d3.json to send the required cookie?
how do I catch the response by status? I'm going to want to do something different for 401 response than 403 response, for example.
Where can I read a more complete documentation or examples for how to do use d3.json? I've always done native ajax because I don't use jquery, but if it's part of the library I'm using anyway, I'd like to learn how to use it. But the documentation says almost nothing about it, and the page it links to isn't helpful either. And most tutorials were for previous versions of d3 and don't work anymore.
Version 5 switched to use the Fetch API, which doesn't send any cookies by default. You can overcome this by adding options for d3.json to pass through to fetch:
d3.json(uri, {credentials: "same-origin"}).then(...);
Or, for cross-origin requests:
d3.json(uri, {credentials: "include"}).then(...);
If a 4XX status (or 5XX) is returned D3 will cause the promise to reject, which you can handle by providing a second callback function to then. I welcome corrections, but I believe there is no way within this function to get the actual status code.
The only mention of the change to Fetch and promises I found in the documentation (at the time of writing) was in the changelog: D3 v5 Changes.

Categories

Resources