Related
I have some parameters that I want to POST form-encoded to my server:
{
'userName': 'test#gmail.com',
'password': 'Password!',
'grant_type': 'password'
}
I'm sending my request (currently without parameters) like this
var obj = {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
},
};
fetch('https://example.com/login', obj)
.then(function(res) {
// Do stuff with result
});
How can I include the form-encoded parameters in the request?
You have to put together the x-www-form-urlencoded payload yourself, like this:
var details = {
'userName': 'test#gmail.com',
'password': 'Password!',
'grant_type': 'password'
};
var formBody = [];
for (var property in details) {
var encodedKey = encodeURIComponent(property);
var encodedValue = encodeURIComponent(details[property]);
formBody.push(encodedKey + "=" + encodedValue);
}
formBody = formBody.join("&");
fetch('https://example.com/login', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
},
body: formBody
})
Note that if you were using fetch in a (sufficiently modern) browser, instead of React Native, you could instead create a URLSearchParams object and use that as the body, since the Fetch Standard states that if the body is a URLSearchParams object then it should be serialised as application/x-www-form-urlencoded. However, you can't do this in React Native because React Native does not implement URLSearchParams.
Even simpler:
fetch('https://example.com/login', {
method: 'POST',
headers:{
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
'userName': 'test#gmail.com',
'password': 'Password!',
'grant_type': 'password'
})
});
Docs: https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
Use URLSearchParams
https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
var data = new URLSearchParams();
data.append('userName', 'test#gmail.com');
data.append('password', 'Password');
data.append('grant_type', 'password');
Just did this and UrlSearchParams did the trick
Here is my code if it helps someone
import 'url-search-params-polyfill';
const userLogsInOptions = (username, password) => {
// const formData = new FormData();
const formData = new URLSearchParams();
formData.append('grant_type', 'password');
formData.append('client_id', 'XXXX-app');
formData.append('username', username);
formData.append('password', password);
return (
{
method: 'POST',
headers: {
// "Content-Type": "application/json; charset=utf-8",
"Content-Type": "application/x-www-form-urlencoded",
},
body: formData.toString(),
json: true,
}
);
};
const getUserUnlockToken = async (username, password) => {
const userLoginUri = `${scheme}://${host}/auth/realms/${realm}/protocol/openid-connect/token`;
const response = await fetch(
userLoginUri,
userLogsInOptions(username, password),
);
const responseJson = await response.json();
console.log('acces_token ', responseJson.access_token);
if (responseJson.error) {
console.error('error ', responseJson.error);
}
console.log('json ', responseJson);
return responseJson.access_token;
};
No need to use jQuery, querystring or manually assemble the payload. URLSearchParams is a way to go and here is one of the most concise answers with the full request example:
fetch('https://example.com/login', {
method: 'POST',
body: new URLSearchParams({
param: 'Some value',
anotherParam: 'Another value'
})
})
.then(response => {
// Do stuff with the response
});
The same technique using async / await.
const login = async () => {
const response = await fetch('https://example.com/login', {
method: 'POST',
body: new URLSearchParams({
param: 'Some value',
anotherParam: 'Another value'
})
})
// Do stuff with the response
}
Yes, you can use Axios or any other HTTP client library instead of native fetch.
var details = {
'userName': 'test#gmail.com',
'password': 'Password!',
'grant_type': 'password'
};
var formBody = [];
for (var property in details) {
var encodedKey = encodeURIComponent(property);
var encodedValue = encodeURIComponent(details[property]);
formBody.push(encodedKey + "=" + encodedValue);
}
formBody = formBody.join("&");
fetch('http://identity.azurewebsites.net' + '/token', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: formBody
})
it is so helpful for me and works without any error
refrence : https://gist.github.com/milon87/f391e54e64e32e1626235d4dc4d16dc8
You can use FormData and URLSearchParams to post as application/x-www-form-urlencoded with the example below:
If you have a form:
<form>
<input name="username" type="text" />
<input name="password" type="password" />
<button type="submit">login</button>
</form>
You can add use the JS below to submit the form.
const form = document.querySelector("form");
form.addEventListener("submit", async () => {
const formData = new FormData(form);
try {
await fetch("https://example.com/login", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams(formData),
});
} catch (err) {
console.log(err);
}
});
*/ import this statement */
import qs from 'querystring'
fetch("*your url*", {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'},
body: qs.stringify({
username: "akshita",
password: "123456",
})
}).then((response) => response.json())
.then((responseData) => {
alert(JSON.stringify(responseData))
})
After using npm i querystring --save it's work fine.
Just Use
import qs from "qs";
let data = {
'profileId': this.props.screenProps[0],
'accountId': this.props.screenProps[1],
'accessToken': this.props.screenProps[2],
'itemId': this.itemId
};
return axios.post(METHOD_WALL_GET, qs.stringify(data))
If you are using JQuery, this works too..
fetch(url, {
method: 'POST',
body: $.param(data),
headers:{
'Content-Type': 'application/x-www-form-urlencoded'
}
})
You can use UrlSearchParams and then do a toString() like so:
Here is a simple way of doing it:
fetch('https://example.com/login', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
body: new UrlSearchParams(...{
'userName': 'test#gmail.com',
'password': 'Password!',
'grant_type': 'password'
})
.toString()
})
.then(res => {
//Deal with response:
})
According to the spec, using encodeURIComponent won't give you a conforming query string. It states:
Control names and values are escaped. Space characters are replaced by +, and then reserved characters are escaped as described in [RFC1738], section 2.2: Non-alphanumeric characters are replaced by %HH, a percent sign and two hexadecimal digits representing the ASCII code of the character. Line breaks are represented as "CR LF" pairs (i.e., %0D%0A).
The control names/values are listed in the order they appear in the document. The name is separated from the value by = and name/value pairs are separated from each other by &.
The problem is, encodeURIComponent encodes spaces to be %20, not +.
The form-body should be coded using a variation of the encodeURIComponent methods shown in the other answers.
const formUrlEncode = str => {
return str.replace(/[^\d\w]/g, char => {
return char === " "
? "+"
: encodeURIComponent(char);
})
}
const data = {foo: "bar߃©˙∑ baz", boom: "pow"};
const dataPairs = Object.keys(data).map( key => {
const val = data[key];
return (formUrlEncode(key) + "=" + formUrlEncode(val));
}).join("&");
// dataPairs is "foo=bar%C3%9F%C6%92%C2%A9%CB%99%E2%88%91++baz&boom=pow"
Just set the body as the following
var reqBody = "username="+username+"&password="+password+"&grant_type=password";
then
fetch('url', {
method: 'POST',
headers: {
//'Authorization': 'Bearer token',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
body: reqBody
}).then((response) => response.json())
.then((responseData) => {
console.log(JSON.stringify(responseData));
}).catch(err=>{console.log(err)})
You can use react-native-easy-app that is easier to send http request and formulate interception request.
import { XHttp } from 'react-native-easy-app';
* Synchronous request
const params = {name:'rufeng',age:20}
const response = await XHttp().url(url).param(params).formEncoded().execute('GET');
const {success, json, message, status} = response;
* Asynchronous requests
XHttp().url(url).param(params).formEncoded().get((success, json, message, status)=>{
if (success){
this.setState({content: JSON.stringify(json)});
} else {
showToast(msg);
}
});
In the original example you have a transformRequest function which converts an object to Form Encoded data.
In the revised example you have replaced that with JSON.stringify which converts an object to JSON.
In both cases you have 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' so you are claiming to be sending Form Encoded data in both cases.
Use your Form Encoding function instead of JSON.stringify.
Re update:
In your first fetch example, you set the body to be the JSON value.
Now you have created a Form Encoded version, but instead of setting the body to be that value, you have created a new object and set the Form Encoded data as a property of that object.
Don't create that extra object. Just assign your value to body.
wrapped fetch in a simple function
async function post_www_url_encdoded(url, data) {
const body = new URLSearchParams();
for (let key in data) {
body.append(key, data[key]);
}
return await fetch(url, { method: "POST", body });
}
const response = await post_www_url_encdoded("https://example.com/login", {
"name":"ali",
"password": "1234"});
if (response.ok){ console.log("posted!"); }
For uploading Form-Encoded POST requests, I recommend using the FormData object.
Example code:
var params = {
userName: 'test#gmail.com',
password: 'Password!',
grant_type: 'password'
};
var formData = new FormData();
for (var k in params) {
formData.append(k, params[k]);
}
var request = {
method: 'POST',
headers: headers,
body: formData
};
fetch(url, request);
So I am making a request to an API endpoint. When I print JSONBody which is the variable data passed to POSTRequest(), I get the JSON I created printed to the log, however when I then try and JSON.Stringify() it, I get returned an empty object?
Was just wondering what I am doing wrong and how to fix it :)
getFileData()
const getFileData = () => {
var data = {}
// DO SOME STUFF HERE TO data
POSTRequest(data);
}
POSTRequest()
const POSTRequest = async (JSONBody) => {
console.log(JSONBody)
console.log(JSON.stringify(JSONBody))
try {
const response = await fetch(API_ENDPOINT, {
method: 'POST',
body: JSON.stringify(JSONBody),
headers: { 'Content-Type': 'application/json' }
});
response.json()
.then(function (res) {
Promise.resolve(res)
.then(function (finalData) {
console.log(finalData);
props.setData(finalData);
});
});
} catch (error) {
console.log(error);
}
}
You're not waiting for the response from the fetch call correctly, try this:
const POSTRequest = async (JSONBody) => {
console.log(JSONBody)
console.log(JSON.stringify(JSONBody))
await fetch(API_ENDPOINT, {
method: 'POST',
body: JSON.stringify(JSONBody),
headers: { 'Content-Type': 'application/json' }
}).then((response) => {
console.log(response);
props.setData(response);
}).catch((error) => {
console.log('POSTRequest error: ' + error)
})
});
I'm trying to POST a JSON object using fetch.
From what I can understand, I need to attach a stringified object to the body of the request, e.g.:
fetch("/echo/json/",
{
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
method: "POST",
body: JSON.stringify({a: 1, b: 2})
})
.then(function(res){ console.log(res) })
.catch(function(res){ console.log(res) })
When using jsfiddle's JSON echo I'd expect to see the object I've sent ({a: 1, b: 2}) back, but this does not happen - chrome devtools doesn't even show the JSON as part of the request, which means that it's not being sent.
With ES2017 async/await support, this is how to POST a JSON payload:
(async () => {
const rawResponse = await fetch('https://httpbin.org/post', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({a: 1, b: 'Textual content'})
});
const content = await rawResponse.json();
console.log(content);
})();
Can't use ES2017? See #vp_art's answer using promises
The question however is asking for an issue caused by a long since fixed chrome bug.
Original answer follows.
chrome devtools doesn't even show the JSON as part of the request
This is the real issue here, and it's a bug with chrome devtools, fixed in Chrome 46.
That code works fine - it is POSTing the JSON correctly, it just cannot be seen.
I'd expect to see the object I've sent back
that's not working because that is not the correct format for JSfiddle's echo.
The correct code is:
var payload = {
a: 1,
b: 2
};
var data = new FormData();
data.append( "json", JSON.stringify( payload ) );
fetch("/echo/json/",
{
method: "POST",
body: data
})
.then(function(res){ return res.json(); })
.then(function(data){ alert( JSON.stringify( data ) ) })
For endpoints accepting JSON payloads, the original code is correct
I think your issue is jsfiddle can process form-urlencoded request only. But correct way to make json request is pass correct json as a body:
fetch('https://httpbin.org/post', {
method: 'POST',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
},
body: JSON.stringify({a: 7, str: 'Some string: &=&'})
}).then(res => res.json())
.then(res => console.log(res));
From search engines, I ended up on this topic for non-json posting data with fetch, so thought I would add this.
For non-json you don't have to use form data. You can simply set the Content-Type header to application/x-www-form-urlencoded and use a string:
fetch('url here', {
method: 'POST',
headers: {'Content-Type':'application/x-www-form-urlencoded'}, // this line is important, if this content-type is not set it wont work
body: 'foo=bar&blah=1'
});
An alternative way to build that body string, rather then typing it out as I did above, is to use libraries. For instance the stringify function from query-string or qs packages. So using this it would look like:
import queryString from 'query-string'; // import the queryString class
fetch('url here', {
method: 'POST',
headers: {'Content-Type':'application/x-www-form-urlencoded'}, // this line is important, if this content-type is not set it wont work
body: queryString.stringify({for:'bar', blah:1}) //use the stringify object of the queryString class
});
After spending some times, reverse engineering jsFiddle, trying to generate payload - there is an effect.
Please take eye (care) on line return response.json(); where response is not a response - it is promise.
var json = {
json: JSON.stringify({
a: 1,
b: 2
}),
delay: 3
};
fetch('/echo/json/', {
method: 'post',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
},
body: 'json=' + encodeURIComponent(JSON.stringify(json.json)) + '&delay=' + json.delay
})
.then(function (response) {
return response.json();
})
.then(function (result) {
alert(result);
})
.catch (function (error) {
console.log('Request failed', error);
});
jsFiddle: http://jsfiddle.net/egxt6cpz/46/ && Firefox > 39 && Chrome > 42
2021 answer: just in case you land here looking for how to make GET and POST Fetch api requests using async/await or promises as compared to axios.
I'm using jsonplaceholder fake API to demonstrate:
Fetch api GET request using async/await:
const asyncGetCall = async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts');
const data = await response.json();
// enter you logic when the fetch is successful
console.log(data);
} catch(error) {
// enter your logic for when there is an error (ex. error toast)
console.log(error)
}
}
asyncGetCall()
Fetch api POST request using async/await:
const asyncPostCall = async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
// your expected POST request payload goes here
title: "My post title",
body: "My post content."
})
});
const data = await response.json();
// enter you logic when the fetch is successful
console.log(data);
} catch(error) {
// enter your logic for when there is an error (ex. error toast)
console.log(error)
}
}
asyncPostCall()
GET request using Promises:
fetch('https://jsonplaceholder.typicode.com/posts')
.then(res => res.json())
.then(data => {
// enter you logic when the fetch is successful
console.log(data)
})
.catch(error => {
// enter your logic for when there is an error (ex. error toast)
console.log(error)
})
POST request using Promises:
fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
// your expected POST request payload goes here
title: "My post title",
body: "My post content."
})
})
.then(res => res.json())
.then(data => {
// enter you logic when the fetch is successful
console.log(data)
})
.catch(error => {
// enter your logic for when there is an error (ex. error toast)
console.log(error)
})
GET request using Axios:
const axiosGetCall = async () => {
try {
const { data } = await axios.get('https://jsonplaceholder.typicode.com/posts')
// enter you logic when the fetch is successful
console.log(`data: `, data)
} catch (error) {
// enter your logic for when there is an error (ex. error toast)
console.log(`error: `, error)
}
}
axiosGetCall()
POST request using Axios:
const axiosPostCall = async () => {
try {
const { data } = await axios.post('https://jsonplaceholder.typicode.com/posts', {
// your expected POST request payload goes here
title: "My post title",
body: "My post content."
})
// enter you logic when the fetch is successful
console.log(`data: `, data)
} catch (error) {
// enter your logic for when there is an error (ex. error toast)
console.log(`error: `, error)
}
}
axiosPostCall()
I have created a thin wrapper around fetch() with many improvements if you are using a purely json REST API:
// Small library to improve on fetch() usage
const api = function(method, url, data, headers = {}){
return fetch(url, {
method: method.toUpperCase(),
body: JSON.stringify(data), // send it as stringified json
credentials: api.credentials, // to keep the session on the request
headers: Object.assign({}, api.headers, headers) // extend the headers
}).then(res => res.ok ? res.json() : Promise.reject(res));
};
// Defaults that can be globally overwritten
api.credentials = 'include';
api.headers = {
'csrf-token': window.csrf || '', // only if globally set, otherwise ignored
'Accept': 'application/json', // receive json
'Content-Type': 'application/json' // send json
};
// Convenient methods
['get', 'post', 'put', 'delete'].forEach(method => {
api[method] = api.bind(null, method);
});
To use it you have the variable api and 4 methods:
api.get('/todo').then(all => { /* ... */ });
And within an async function:
const all = await api.get('/todo');
// ...
Example with jQuery:
$('.like').on('click', async e => {
const id = 123; // Get it however it is better suited
await api.put(`/like/${id}`, { like: true });
// Whatever:
$(e.target).addClass('active dislike').removeClass('like');
});
Had the same issue - no body was sent from a client to a server.
Adding Content-Type header solved it for me:
var headers = new Headers();
headers.append('Accept', 'application/json'); // This one is enough for GET requests
headers.append('Content-Type', 'application/json'); // This one sends body
return fetch('/some/endpoint', {
method: 'POST',
mode: 'same-origin',
credentials: 'include',
redirect: 'follow',
headers: headers,
body: JSON.stringify({
name: 'John',
surname: 'Doe'
}),
}).then(resp => {
...
}).catch(err => {
...
})
This is related to Content-Type. As you might have noticed from other discussions and answers to this question some people were able to solve it by setting Content-Type: 'application/json'. Unfortunately in my case it didn't work, my POST request was still empty on the server side.
However, if you try with jQuery's $.post() and it's working, the reason is probably because of jQuery using Content-Type: 'x-www-form-urlencoded' instead of application/json.
data = Object.keys(data).map(key => encodeURIComponent(key) + '=' + encodeURIComponent(data[key])).join('&')
fetch('/api/', {
method: 'post',
credentials: "include",
body: data,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
The top answer doesn't work for PHP7, because it has wrong encoding, but I could figure the right encoding out with the other answers. This code also sends authentication cookies, which you probably want when dealing with e.g. PHP forums:
julia = function(juliacode) {
fetch('julia.php', {
method: "POST",
credentials: "include", // send cookies
headers: {
'Accept': 'application/json, text/plain, */*',
//'Content-Type': 'application/json'
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" // otherwise $_POST is empty
},
body: "juliacode=" + encodeURIComponent(juliacode)
})
.then(function(response) {
return response.json(); // .text();
})
.then(function(myJson) {
console.log(myJson);
});
}
It might be useful to somebody:
I was having the issue that formdata was not being sent for my request
In my case it was a combination of following headers that were also causing the issue and the wrong Content-Type.
So I was sending these two headers with the request and it wasn't sending the formdata when I removed the headers that worked.
"X-Prototype-Version" : "1.6.1",
"X-Requested-With" : "XMLHttpRequest"
Also as other answers suggest that the Content-Type header needs to be correct.
For my request the correct Content-Type header was:
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
So bottom line if your formdata is not being attached to the Request then it could potentially be your headers. Try bringing your headers to a minimum and then try adding them one by one to see if your problem is resolved.
If your JSON payload contains arrays and nested objects, I would use URLSearchParams and jQuery's param() method.
fetch('/somewhere', {
method: 'POST',
body: new URLSearchParams($.param(payload))
})
To your server, this will look like a standard HTML <form> being POSTed.
You could do it even better with await/async.
The parameters of http request:
const _url = 'https://jsonplaceholder.typicode.com/posts';
let _body = JSON.stringify({
title: 'foo',
body: 'bar',
userId: 1,
});
const _headers = {
'Content-type': 'application/json; charset=UTF-8',
};
const _options = { method: 'POST', headers: _headers, body: _body };
With clean async/await syntax:
const response = await fetch(_url, _options);
if (response.status >= 200 && response.status <= 204) {
let data = await response.json();
console.log(data);
} else {
console.log(`something wrong, the server code: ${response.status}`);
}
With old fashion fetch().then().then():
fetch(_url, _options)
.then((res) => res.json())
.then((json) => console.log(json));
**//POST a request**
const createTodo = async (todo) => {
let options = {
method: "POST",
headers: {
"Content-Type":"application/json",
},
body: JSON.stringify(todo)
}
let p = await fetch("https://jsonplaceholder.typicode.com/posts", options);
let response = await p.json();
return response;
}
**//GET request**
const getTodo = async (id) => {
let response = await fetch('https://jsonplaceholder.typicode.com/posts/' + id);
let r = await response.json();
return r;
}
const mainFunc = async () => {
let todo = {
title: "milan7",
body: "dai7",
userID: 101
}
let todor = await createTodo(todo);
console.log(todor);
console.log(await getTodo(5));
}
mainFunc()
I think that, we don't need parse the JSON object into a string, if the remote server accepts json into they request, just run:
const request = await fetch ('/echo/json', {
headers: {
'Content-type': 'application/json'
},
method: 'POST',
body: { a: 1, b: 2 }
});
Such as the curl request
curl -v -X POST -H 'Content-Type: application/json' -d '#data.json' '/echo/json'
In case to the remote serve not accept a json file as the body, just send a dataForm:
const data = new FormData ();
data.append ('a', 1);
data.append ('b', 2);
const request = await fetch ('/echo/form', {
headers: {
'Content-type': 'application/x-www-form-urlencoded'
},
method: 'POST',
body: data
});
Such as the curl request
curl -v -X POST -H 'Content-type: application/x-www-form-urlencoded' -d '#data.txt' '/echo/form'
You only need to check if response is ok coz the call not returning anything.
var json = {
json: JSON.stringify({
a: 1,
b: 2
}),
delay: 3
};
fetch('/echo/json/', {
method: 'post',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
},
body: 'json=' + encodeURIComponent(JSON.stringify(json.json)) + '&delay=' + json.delay
})
.then((response) => {if(response.ok){alert("the call works ok")}})
.catch (function (error) {
console.log('Request failed', error);
});
// extend FormData for direct use of js objects
Object.defineProperties(FormData.prototype, {
load: {
value: function (d) {
for (var v in d) {
this.append(v, typeof d[v] === 'string' ? d[v] : JSON.stringify(d[v]));
}
}
}
})
var F = new FormData;
F.load({A:1,B:2});
fetch('url_target?C=3&D=blabla', {
method: "POST",
body: F
}).then( response_handler )
you can use fill-fetch, which is an extension of fetch. Simply, you can post data as below:
import { fill } from 'fill-fetch';
const fetcher = fill();
fetcher.config.timeout = 3000;
fetcher.config.maxConcurrence = 10;
fetcher.config.baseURL = 'http://www.github.com';
const res = await fetcher.post('/', { a: 1 }, {
headers: {
'bearer': '1234'
}
});
I want to retrieve the JSON response from the api call I am doing. Example, I want to retrieve something like this:
{"error":{},"success":true,"data":{"user":"tom","password":"123","skill":"beginner","year":2019,"month":"Mar","day":31,"playmorning":0,"playafternoon":1,"playevening":1}}
This is my API call using fetch in react. (yes I know sending password in URL is bad, it's for a school project)
fetch('/api/user/'+ user + '?password=' + password, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
}}).then((res) => {
console.log(res); //I want to get the JSON stuff here
})
This is the API call I am calling.
app.get('/api/user/:user', function (req, res) {
// console.log(JSON.stringify(req));
// var user = req.body.user;
// var password = req.body.password;
var user = req.params.user;
var password = req.query.password;
console.log(user, password);
var result = { error: {} , success:false};
if(user==""){
result["error"]["user"]="user not supplied";
}
if(password==""){
result["error"]["password"]="password not supplied";
}
if(isEmptyObject(result["error"])){
let sql = 'SELECT * FROM user WHERE user=? and password=?;';
db.get(sql, [user, password], function (err, row){
if (err) {
res.status(500);
result["error"]["db"] = err.message;
} else if (row) {
res.status(200);
result.data = row;
result.success = true;
} else {
res.status(401);
result.success = false;
result["error"]["login"] = "login failed";
}
res.json(result);
});
} else {
res.status(400);
res.json(result);
}
});
When I do console.log(res) in the fetch call, this is what is printed:
Response {type: "basic", url: "http://localhost:3000/api/user/tim?password=123", redirected: false, status: 200, ok: true, …}body: (...)bodyUsed: falseheaders: Headers {}ok: trueredirected: falsestatus: 200statusText: "OK"type: "basic"url: "http://localhost:3000/api/user/tim?password=123"proto: Response
When I visit the website, the output is:
{"error":{},"success":true,"data":{"user":"tom","password":"123","skill":"beginner","year":2019,"month":"Mar","day":31,"playmorning":0,"playafternoon":1,"playevening":1}}
This is what I want.
In general, this is how you return the response body from the Promise.
fetch(`${baseUrl}/api/user/${user}?password=${password}`, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
}})
.then(response => response.json())
.then(data=> {
console.log(data);
})
Try this way to parse the response:
fetch('/api/user/'+ user + '?password=' + password, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
}}).then(async (res) => {
const raw = await res.text();
const parsed = raw ? JSON.parse(raw) : { success: res.ok };
console.log(parsed);
})
In this case you can also add some checks for response statuses (if you want, of course) along with parsing the result JSON.
for you to get the JSON body content from the response, you need to use json()
fetch('/api/user/'+ user + '?password=' + password, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
}}).then((res) => {
const jsonData = res.json();
console.log(jsonData);
})
try this
fetch(${baseUrl}/api/user/${user}?password=${password},{
method:'GET',
headers: {
'Accept': 'application/json',
'Content-Type':
'application/json',
}}) .then(async(response ) => {
await response.json()
})
$ajax server response:
{"username":"","password":""}
fetch server response:
{"{\"username\":\"\",\"password\":\"\"}":""}
Why aren't they the same? I need the same server response. I'm using PHP+Apache
Here is my code:
import $ from 'jquery';
export function FetchData(type, data){
const serverUrl = 'http://localhost/oms/'+ type + ".php";
return new Promise((resolve, reject) => {
$.ajax({
type: 'POST',
url: serverUrl,
data //body : {username: "username", password:"password"}
})
.done(function(res) {
//console.log(res);
resolve (res);
})
.fail(function(jqXHR, exception){
//alert('server error()');
reject(jqXHR);
});
fetch(serverUrl,{
method: 'POST',
headers: {
Accept: '*/*',
'Content-Type': 'application/x-www-form-urlencoded',
//'Access-Control-Allow-Origin': '*',
//'Access-Control-Allow-Methods': 'POST,GET,OPTIONS,PUT,DELETE',
//'Access-Control-Allow-Headers': 'Content-Type,Accept',
},
body: JSON.stringify(data)
//body : {username: data.username, password: data.password}
})
.then((response) => response.json())
.then((responseJson) => {
resolve(responseJson);
})
.catch((error) => {
reject(error);
});
});
}
The responses are essentially the same just that response from fetch library returns a Stringified JSON.
You need to convert it into actual JS object.
const responseData = JSON.parse(response.json())
This occurs because you're sending the content type application/x-www-form-urlencoded with JSON data you need to change it to application/json like
export const FetchData = (type, data) => {
let serverUrl = 'http://localhost/oms/'+ type + ".php";
let data = {
username: data.username,
password: data.password
};
return new Promise((resolve, reject) => {
fetch(serverUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
credentials: 'include',
body: JSON.stringify(data),
})
.then((response) => response.json())
.then((responseJson) => {
resolve(responseJson)
})
.catch((error) => {
reject(error)
})
})
};
I added credentials it's read-only property of the Request interface indicates whether the user agent should send cookies from the other domain in the case of cross-origin requests. This is similar to XHR’s withCredentials flag
If you want to use something smaller to jQuery you can use Axios It's XMLHttpRequests
If you get some CORS issues this will help you