I am writing a basic JS function in Microsoft 365 Excel add-in generated using yeoman generator which I just want to fetch some data from a url, while fetching from https it is working fine.
But while doing the same with http I get an error saying TypeError: Failed to fetch. Now, I understand that I can't fetch from a http link but is there a way around.
Have included <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"> in the html file.
Code
// Fetch json value
console.log(`Fetching`);
var url = "http://1<ip>:<port>/fetch_api";
//var url = "https://api.publicapis.org/entries";
const response = await fetch(url, {
method: 'GET',
headers: {
accept: 'application/json',
},
});
if (!response.ok) {
throw new Error(`Error! status: ${response.status}`);
}
const result = await response.json();
console.log(result);
Firstly you made mistype in headers dictionary
headers: { 'Content-Type': 'application/json' }
Then rememeber that this function have to be asynch.
no need to write that much code to get requests using fetch.
get request is the default method. you can write just fetch(URL). for another type of requests you should write method, headers, body, etc.
just write this function and invoke it.
async function getData () {
const URL = 'your_url'
let response = await fetch(URL)
let data = await response.json()
console.log(data)
}
I am using an async await for fetching data. for any type of promise request you should use async await, this will help you to handle promises.
Related
So I want to convert a python script to javascript. The script features a post request, which is supposed to send only a string. I found somewhere that stringname.json() somehow works(which it does), but I am not sure how it works. How do I replicate this in javascript?
Code:
user_info = requests.post('url',
headers=headers,
json = username.json()
Edit: This was a dumb question, ignore this
fetch returns a Promise, so you need to either await it in an async function or use .then
const userInfo = await fetch('url', {
method: "POST",
headers: headers,
body: JSON.stringify(username),
}
There were similar discussion here Firebase API doesn't respond with common error codes using Axios on react native, but guy was using Axios. I would like to use Fetch API, and hope there are similar solution using this API for current case.
The issue is when I get error from Firebase REST API statusText of response is empty. I only got status code.
If I will make same request with the same url and options using Axios I will get error description which defied by Firebase API (like TOKEN_EXPIRED, USER_DISABLED, USER_NOT_FOUND, INVALID_REFRESH_TOKEN, MISSING_REFRESH_TOKEN etc.) using console.log(error.response.data.error.message)
How I can achieve same output with Fetch API?
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: bodyString
});
if (response.ok) {
const payload = await response.json();
return payload as HttpResponse;
} else {
throw new Error(`Server error: ${response.statusText}. Status: ${response.status}`);
}
I don't know how I missed to check this.
The solution: await response.text()
I'm new to Web programming, and I wanted to know how to make easy requests to connect to an API if the only information I have are the URL, a login and password using pure Typescript or Javascript.
The goal is to retrieve an access Token.
I would advise using the browsers fetch API which uses promises.
let us begin here. In the past browsers offered AJAX calls but ever since modern JS came through with promises, everything got really easy. You can find out more about promises here.
let us consider an example similar to your case where you have a url endpoint, and some data you want to send to the url. we expect that the url with respond with a JSON payload containing a token.
// so we will define our constants here
const url = 'http://localhost/login';
const username = 'username';
const password = 'password';
// now we configure the fetch request to the url endpoint.
// we should probably put it inside a separate function since
// you're using a browser, you probably will bind this request
// to a click event or something.
function login() {
return fetch(url, {
// in the case of a login request most APIs use the POST method offered by
// RESTful APIs
method: 'post', // can be 'get', 'put', 'delete', and many more
// now we set any needed headers specified by the API
headers: {
// most APIs I have worked with use
'Content-Type': 'application/json',
// but some might need more, they will specify anyway.
},
// because we are using the 'post' method then we will need to add
// a body to the request with all our data, body excepts a string so
// we do the following
body: JSON.stringify({
username: username,
password: password,
}),
})
// Now we handle the response because the function returns a promise
.then((response) => {
// An important thing to note is that an error response will not throw
// an error so if the result is not okay we should throw the error
if(!response.ok) {
throw response;
}
// since we expect a json response we will return a json call
return response.json();
})
}
now since you are using a browser you will have to bind the function to
an element to trigger the call
// will define a self calling arrow function that will do the event binding
((button) => {
button.addEventListener('click', (event) => {
// we then call the function here.
login()
.then((response) => {
// side note, you could destructure the response argument as { token }
// then just reference token instead.
// recall that we expect this function to have a 'token' key in
// the response payload...so let us log it just to make sure
console.log(result.token);
})
});
// we add the button reference as the argument
})(document.querySelector('#submit'));
References:
Promises
RESTful
I hope this helps give a better idea on the task you have, good luck
u can use axios for js/ts
like this example :
getToken = () => {
axios.post('http://localhost/login',{
username: username,
password: password,
}).then((response) => {
let data = response.data;
//do whatever u want here eg :set token to local storage
localStorage.set('token',data.token);
}).catch((error) => {
console.log(error);
});
};
getToken();
I am using fetch to get the API response for GET and POST requests. When an error occurs, I am able to see the status code and the text i.e, 400 Bad Request. However, there is additional information being passed that explains why the error was thrown (i.e. username did not match). I can see this additional message in the response payload via Firefox developer tool's console but I am not sure how to get it via handling the fetch response.
Here's an example request:
fetch(url, {
method: 'POST',
body: JSON.stringify({
name: name,
description: description
}),
headers: {
"Content-type": "application/json; charset=UTF-8",
"Authorization": "Bearer " + token
}
}).then(response => {
if (!response.ok) {
throw Error(response.statusText)
}
return response
})
.catch(error => {
console.log(error)
})
Any ideas? Thanks.
Thank you everyone for your suggestions.
This tutorial helped me understand what to do.
https://css-tricks.com/using-fetch/
My problem was that when there is an error, the response is not JSON, it's text. So I needed to do something like this (taken from css-tricks.com):
fetch('https://api.github.com/users/chriscoyier/repos')
.then(response => response.text())
.then(data => {
console.log(data)
});
You seem to be passing only the statusText field of the response, which corresponds to the HTTP status code (And not the response body) - for example Bad Request for HTTP response code 400.
You can read the response body using one of the methods defined on the Response object returned by the fetch API. For example, if you're expecting a JSON response body, you can have:
const onSuccess = response => {
// Do something with the response
// What you return from here will go to the next .then
}
const onFailure = response => {
// response.json() returns a promise that resolves to the JSON sent in the body
// Note that whatever is returned from here will go to the next .then
// To go to the next .catch, you can throw from here
return response.json().then(jsonResponse => console.log(jsonResponse))
}
fetch(url, {
method: 'POST',
body: JSON.stringify({
name: name,
description: description
}),
headers: {
"Content-type": "application/json; charset=UTF-8",
"Authorization": "Bearer " + token
}
}).then(response => {
if (!response.ok) {
throw response
}
return response
})
.then(onSuccess, onFailure)
.catch(err => { /* Any error thrown from the handlers will be caught here */ })
You can have a look at the Response object documentation for more details.
Based off the docs, I'd do something more along the lines of this:
const response = await fetch('http://example.com/movies.json')
const myJson = await response.json();
console.log(JSON.stringify(myJson));
Otherwise you have to do everything inside of your .then().
In regards to the additional text you are looking for, that's totally dependent on the response object, and I have no way of knowing without seeing it.
#Voxum, your answer is missing important info, like a method..and ; await is good, but remember it should be in an async function, and you dont need to use it if you "thenify" .then() as that returns the promise. from the Fetch docs, that is their basic get/HTML example. i think the OP is asking for a API call for different types of methods, which will require a more advanced setup.
The thing is with a 400 response, the server is not giving you a response message as the 404 (for example) is telling you the page is not found. Usually the only time a server will give you a response message is when you get a good (success/200). there will usually be a message at response.json() or response.text() depending on your data coming back.
after you call fetch with the url, method and any headers use
.then((response) => {console.log(response.json());}); for json and use
.then((response) => {console.log(response.text());}); for xml/text
OP has the fetch set up properly but just needs to use response.json() or response.text(). again, a 200 response can still be a "incorrect password" and this is where you'll use this. don't expect a response body on the 400/500s. good luck!
can somebody explain to me why when I am using fetch and accessed my nodejs api - it is authorized but when I tried using axios to access my api - it is unauthorized.
This is the code I am using in fetch (It came from tutorial: https://medium.com/#alexanderleon/implement-social-authentication-with-react-restful-api-9b44f4714fa) Bec I am studying his way of authenticating using passport-facebook-token.
(client -->(login fbsdk)--> fb --> (access token)--> client -->(pass access token)--> nodejs api --> (get credentials) --> passport-fb-token --> (send credentials) --> nodejs api --> (credentials)--> client)
const tokenBlob = new Blob([JSON.stringify({access_token: response.accessToken}, null, 2)], {type : 'application/json'});
const options = {
method: 'POST',
body: tokenBlob,
mode: 'cors',
cache: 'default'
};
fetch('http://localhost:4000/api/v1/auth/facebook', options).then(r => {
const token = r.headers.get('x-auth-token');
r.json().then(user => {
if (token) {
this.setState({isAuthenticated: true, user, token})
}
});
})
This is the code of my axios
axios({
method: 'post',
url: 'http://localhost:4000/api/v1/auth/facebook',
headers: {
'Access-Control-Allow-Origin': '*',
},
data: {
access_token: response.access_token
}
})
.then((res) => console.log(res))
.catch((err) => console.log(err));
You should configure axios to use your token in one central place. For example
export const configureAxios = (token) => {
axios.interceptors.request.use(req => {
// don't give our token to non-our servers
if (isDomesticRequest(req.url)) {
req.headers.Authorization = `Bearer ${token}`;
}
return req;
});
}
This blog should help you get your answer in detail:
Fetch vs. Axios.js for making http requests
Axios is a Javascript library used to make http requests from node.js
or XMLHttpRequests from the browser and it supports the Promise API
that is native to JS ES6. Another feature that it has over .fetch() is
that it performs automatic transforms of JSON data.
If you use .fetch() there is a two-step process when handing JSON
data. The first is to make the actual request and then the second is
to call the .json() method on the response.
The .fetch() method is a great step in the right direction of getting
http requests native in ES6, but just know that if you use it there
are a couple of gotchas that might be better handled by third-party
libraries like Axios.