Post request to JSON server through FETCH api refreshes the page - javascript

I am trying to send POST requests through fetch API to JSON-server. Function is called on a simple button click (type 'button', not 'submit'). When I replace POST request with GET request everything works like it supposed to, but with POST I have a problem. Request passes, on the JSON-server entity gets created but keeps refreshing the page after each request. Also, I don't have a response from JSON-server, google chrome says 'Failed to load response data'.
Where I'm making a mistake?
const comment = {
text: "test comment",
article_id: 3
};
console.log(JSON.stringify(comment));
const options = {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(comment)
}
fetch(`${URL_COMMENTS}`, options)
.then(response => { return response.json() })
.then(data => {
console.log(data)
});

If you use Live Server extension, try disabling that and try again.

Check out for Json sever port number running on your machine
attach the html form code
So we can try it on oru local machine to reproduce the issue.... Which help us to resolve the issue easy

Related

How to make an axios post request that is structured like a form post request?

I am having some problems with trying to customize some code for Next-Auth, an authentication library for.Next.Js.
I want to be able to use Axios to manually make the post request rather than using a <form> element.
When I do the following, I have success.
<form method='POST' action='/api/auth/signout'>
<input name='csrfToken' value={csrfToken}/>
<button type='submit'>Submit</button>
</form>
But, when I try to do the same thing with axios, it doesn't work. I am attempting to call Next-auth's Signout endpoint, which I can do just fine using this html form element. I am expecting that the application with log the user out when calling this endpoint. When I do so with the form input, then it logs the user out. When calling the same endpoint with axios, it does not log the user out and instead nothing is happening
My axios request is
const submitForm = async () => {
if (csrfToken) {
const params = new URLSearchParams();
params.append("csrfToken", csrfToken);
try {
const response = await axios({
method: "POST",
url: "http://localhost:3000/api/auth/signout",
data: params,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
}).then((res) => console.log(res));
} catch (err) {
console.log(err);
}
}
};
I have tried adding additional headers that I saw on the request that works properly, like:
"Upgrade-Insecure-Requests": "1",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-User": "?1"
I have tried making it multipart form data, passing it simply a body of {csrfToken}, and anything else I could think of.
Any tips or things that I might be overlooking?
I can't figure out why I am unable to make this work. I am using ANTD, rather than using regular html <form> elements throughout the application and would love to be able to use that additional functionality.
Edited:
I found the solution after a lot of headache. It turns out that everything was functioning as it should have previously, but Next-Auth has an issue with updating the client-side 'session' object when you make a manual change on the server side.
I fixed this by doing the following:
const res = await axios.post("/api/auth/signout", { csrfToken }).then(
async ({ request: { responseURL } }) =>
await router
.push(responseURL)
//this is from https://github.com/nextauthjs/next-auth/issues/596#issuecomment-943453568
//force the client side to refresh and revalidate since it doesn't want to do so on its own.
.then(() => document.dispatchEvent(new Event("visibilitychange")))
.catch((err) =>
console.log("err refreshing client side session ", err)
)
);
The trick that i was missing was the document.dispatchEvent(new Event('visibilitychange'). This is the magical piece that allows you to force the client side next-auth session to sync with cookies/db.
see here for more info https://github.com/nextauthjs/next-auth/issues/596#issuecomment-943453568

Unable to retrieve data from axios GET request

I've been trying to send a GET request to an api to fetch data using Axios but always get a response object with status, headers, config, agents etc and response.data is always empty.
For example, the following code returns me an Axios response object with the hasBody set to true and data being empty.
axios.get(`https://fantasy.premierleague.com/api/leagues-classic/12000/standings/`).then(response => {console.log(response);
console.log(response.data);});
However, when I switched over to using Request library which has been deprecated, I am able to get the response body. For example, the following code works:
request(`https://fantasy.premierleague.com/api/leagues-classic/12000/standings/`, { json: true }, (err, res, body) => {
if (err) { return console.log(err); }
console.log(body);
});
Can someone tell me what am I doing wrong and how can I get the response body using axios? I'm a beginner and have spent hours trying to figure out so I would really appreciate any form of help.
It's not an axios library issue. From what I can tell, the server does't like the user-agents starting with "axios/". Specifying some user agent gives you the expected result:
const axios = require("axios");
axios.get(`https://fantasy.premierleague.com/api/leagues-classic/12000/standings`, {
headers: {
'user-agent': 'not axios',
}
}).then(response => {
console.log(response.data);
});
As for why the requests library works but axios does not: axios is setting the user-agent header to something like axios/0.21.1 or whatever version you have. requests on the other side, leaves the user-agent header unset. It's the server right to handle the request as he pleases.
I have verified the response from this URL https://fantasy.premierleague.com/api/leagues-classic/12000/standings/ - there is no data property in the response
Try like below to read the values:
It seem like your URL at https://fantasy.premierleague.com/api/leagues-classic/12000/standings/ had invalid response body.

How to send a POST request using an html button

I want to send a POST request to the URL, for example, I want to create a database in influxdb by pressing this button.
So far I tried this but cannot make it work
<button id="post-btn">Post</button>
<script>
const button = document.getElementById('post-btn');
button.addEventListener('click', async _ => {
try {
const response = await fetch('http://00.00.000.000:2000/query', {
method: 'post',
body: {
"q=create database telecom"
}
});
console.log('Completed!', response);
} catch(err) {
console.error(Error: ${err});
}
});
</script>
The error it gives me is "Failed to fetch"
You have to deal with Cross-Origin Resource Sharing, so you need to allow your Grafana origin on the InfluxDB server side.
Anyway it looks very unsafe. If you can call create database telecom, then also other Grafana user can requests own queries, e.g. drop database telecom. Grafana should have read only access and InfluxDB should be managed outside of Grafana.

When to set the headers explicitly when making HTTP request in NodeJS application

So I was having a look at a codebase of a NodeJS application and there were some specific functions making HTTP requests to the backend. To be exact, those functions were making a GET request to the backend and one thing that I found confusing was that in some of the functions, the headers were mentioned explicitly whereas, in some other functions who were making the GET request, there was no mention of headers (i.e. headers were not being set explicitly). Below is an example:
In the code below, the function is making a GET request and there's no mention of headers (i.e. the headers are not being set explicitly):
// Method for fetching a single post from the backend on the basis of the post ID
export const singlePost = (postID) => {
return fetch(http://localhost:8080/post/${postID}, {
method: "GET",
})
.then((response) => {
return response.json();
})
.catch((error) => {
console.log(error);
});
};
In the code below, the function is making a GET request and the headers are being set explicitly:
// Helper Method for making the call to the backend and fetching all their details of all the posts
export const list = (page) => {
return fetch(http://localhost:8080/posts/?page=${page}, {
method: "GET",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
})
.then((response) => {
return response.json();
})
.catch((error) => console.log(error));
};
Now coming to the main question, could someone please explain to me when are we supposed to set the headers explicitly not only in just GET request but in other general HTTP requests as well (i.e. POST, PUT, OPTION etc).
It would be really great if some could refer a source or explain this concept here. Thanks!
HTTP request header is the information, in the form of a text record, that a user's browser sends to a Web server containing the details of what the browser wants and will accept back from the server. The request header also contains the type, version and capabilities of the browser that is making the request so that server returns compatible data.
Check this https://code.tutsplus.com/tutorials/http-headers-for-dummies--net-8039

How to redirect the user to a different page when using fetch and await?

I have been trying to redirect the user to a different page after a POST call to my site api with fetch and await. I am receiving a response which says GET localhost:10004/ page. Usually in $.ajax or xmlHTTPRequest it redirects automatically but when using the new fetch and await syntax it fails to redirect automatically.
Here is my code.
I have already tried using redirect = "follow" it does not redirect after that.
fetch('http://localhost:10004/api', {
method: 'POST', // or 'PUT'
body: JSON.stringify(obj),
headers: {
'Content-Type': 'application/json'
},
redirect: 'follow'
})
.then(response => {
//what to write here to redirect the user
}).catch(error => {
console.error('Error:', error);
});
EDIT:1
Changed the key redirected to redirect.
I would like to clarify that i wanted to achieve the redirect without the window.location methods like window.location.replace or window.location.href .So after a month or so with grappling with the issue. I think I have cornered the issue so when using the fetch api.
The browser does send another request to server to the redirected location from the client side.But the interesting part is it is not a document request it is a fetch request which the browser assumes it does not have to render and is asynchronous the client side then receives the html output but the browser refuses to render the page in the window.
you can achieve your redirect by setting window.location Object:
window.location.href = "https://www.google.com"
https://developer.mozilla.org/en-US/docs/Web/API/Window/location
In your example you are using only single then but it should be two like below.
fetch('https://httpbin.org/post', { method: 'POST', body: 'a=1' })
.then(res => res.json()) // expecting a json response
.then(json => {
console.log(json)
window.location.href = data.redirect;
});

Categories