I'm currently developing client side for my app.
When i try to login user in case where email and password is correct everything works fine but sending error data isn't occuring because status(400) blocks it.
Here is part of my server side code for user login that isn't sending object with isAuth, message, err:
User.findOne({ email: req.body.email }, (err, user) => {
if (!user) return res.status(400).json({
isAuth: false,
message: "Auth failed, bad email",
err
})
But when I make it like that i get the error with all parameters:
User.findOne({ email: req.body.email }, (err, user) => {
if (!user) return res.json({
isAuth: false,
message: "Auth failed, bad email",
err
})
Another strange thing is that when I send bad request with Postman I'm getting all the response data.
And here is client side function that is making request, the console.log(request) part is blocked because of status 400:
const submitForm = async (e) => {
e.preventDefault()
const request = await axios.post('/api/login', { email: email, password: password }).then(res => res.data)
console.log(request)
dispatch({
type: "USER_LOGIN",
payload: request
})
}
And here is some of Chrome stuff from console:
xhr.js:166 POST http://localhost:3000/api/login 400 (Bad Request)
createError.js:17 Uncaught (in promise) Error: Request failed with status code 400
at createError (createError.js:17)
at settle (settle.js:19)
at XMLHttpRequest.handleLoad (xhr.js:60)
There was an axios error/bug.
I have rewrited my code using fetch API. It seems that axios has some kind of bug when it comes to handling 4xx and 5xx status.
Now client part looks like this:
const submitForm = async (e) => {
e.preventDefault()
const request = await fetch('/api/login', {
method: 'POST',
body: JSON.stringify({ email, password }),
headers: {
'Content-Type': 'application/json',
}
}).then(res => res.json())
console.log(request)
dispatch({
type: "USER_LOGIN",
payload: request
})
}
At the server side everything is just as it should be, return res.status(400).send(data)
Related
I am trying to send a DELETE request to my backend server, but I keep getting this response printed to my console:
Response {type: 'cors', url: 'http://localhost:3003/delete', redirected: false, status: 200, ok: true, …}
body: (...)
bodyUsed: false
headers: Headers {}
ok: true
redirected: false
status: 200
statusText: "OK"
type: "cors"
url: "http://localhost:3003/delete"
[[Prototype]]: Response
I don't know why this is happening.
server.js
const express = require('express')
const knex = require('knex')
const cors = require('cors')
const db = knex({
client: 'pg',
connection: {
host: '127.0.0.1',
user: 'postgres',
password: 'psql',
database: 'blogspot',
port: 5432
}
});
const app = express();
app.use(express.json())
app.use(cors())
// Delete Blog
app.delete('/delete', (req, res) => {
const {id} = req.body;
db.select('*').from('blogs')
.where({
id: id
})
.del()
.then(() => {
res.json('Deleted Successfully')
})
.catch(err => res.status(404).json('An error occured'))
})
fetchAPI.js
function deleteBlog (blog) {
fetch('http://localhost:3003/delete', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(blog)
}).then(resp => {
console.log(resp)
if (resp === 'Deleted Successfully') {
navigate(0)
} else if (resp === 'An error occured') {
console.log('Something went wrong')
} else {
console.log('ERROR')
}
})
}
I keep getting 'ERROR' printed to my console along with the cors response I pasted above. When I refresh, I find that the blog has been deleted, but the response was definitely an error since navigate(0) wasn't run and ERROR was printed to my console. I have tried removing the 'Content-Type': 'application/json' header and sending the id as request params instead but I got the same error.
The fact that the response is of type "cors" just means that some contents are filtered by CORS policy (see https://developer.mozilla.org/en-US/docs/Web/API/Response/type) but you didn't get any error code, the statusCode is 200.
Since your response content type is JSON, you must also resolve the json parsing before reading the response:
function deleteBlog(blog) {
fetch('http://localhost:3003/delete', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(blog)
})
.then(data => data.json())
.then(resp => {
// I also suppose that you will more likely find
// your "Deleted successfully" in the resp.body property, so :
if (resp.body === 'Deleted Successfully') {
navigate(0)
} else if (resp.body === 'An error occured') {
console.log('Something went wrong')
} else {
console.log('ERROR')
}
})
}
I am facing some issue while downloading file using node.js. I have scenario like my angular component is sending the file request. in my first node server I am doing the token validation and then redirecting to another node server where actually the execution happens. I am explaining my code below.
service.ts:
submitAndDownloadFile(formdata : any ){
const token = localStorage.getItem('token')
let headers = new HttpHeaders({
Authorization: 'Basic ' + token
})
const cecID = localStorage.getItem('cec');
const AppUrl = `${environment.nodeJsBaseUrl}:${environment.hostingNodeJsContainerPort}/convert-test-cases/${cecID}`;
return this.httpClient.post(AppUrl, formdata, { responseType: 'blob', observe : 'response', headers : headers});
}
Here I am sending the request to my first node.js server which code has given below.
app.js(first:port-8000):
router.post('/convert-test-cases/:id', middleware.auth, (req, res) => {
try{
let postRequestOptions = {
url: '',
method: 'POST',
json: true,
headers: {},
body: {},
};
postRequestOptions.url = 'http:localhost:9000/convert-test-cases';
postRequestOptions.headers = {
'Content-Type': 'application/json',
};
postRequestOptions.body = req.body;
request(postRequestOptions, async (error, response, pathList) => {
if(error) {
console.log('error', error);
}else{
res.send(pathList);
}
})
}catch(e){
responseObj = {
status: 'error',
msg: 'Error occurred while processing your request',
body: null
}
return res.send(responseObj);
}
})
Here I am doing the token validation using middleware.auth and sending same request to another node.js file which code is explained below.
app.js:(second-port-9000):
router.post('/convert-test-cases', async (req, res) => {
try{
let response = await ctcCtrl.convertTestCase(req.body, req.files);
if(response.status == 'success'){
res.set('Access-Control-Expose-Headers','*, Content-Disposition');
return res.download(response.fileName,response.fileName);
}else{
return res.send(response);
}
}catch(e){
responseObj = {
status: 'error',
msg: 'Error occurred while processing your request',
body: null
}
return res.send(responseObj);
}
})
Here only I am doing some execution and downloading the file. If I am connecting angular to node-9000 its working fine but my requirement is first I have to connect to port-8000 to some token validation and after that I have to send same req.body and re.file to app.js which is running in 9000 using request module. As per my code its not working at all.
I am converting a code that connected AWS Lambda to nanoexpress. My VueJS frontend was not passing data correctly so I started to do changes and now I cannot reach the backend at all and I have no idea why.
The backend is trivial:
const nanoexpress = require('nanoexpress');
const app = nanoexpress();
app.post('/v1/authorizeUser', async (req) => {
console.log(req);
const { email, password } = req.body;
console.log(email);
return { status: 'Ok', body: req.body };
});
app.listen(3000).then(r => console.log('started'));
This is the original store.js code. I am able to send the request from Vue app in Chrome but it is not parsed correctly. Probably because of missing or incorrect content type
const axiosResponse = await axios.post(`${API_ENDPOINT}/authorizeUser`, JSON.stringify({
email: payload.email,
password: payload.password,
}));
and the server log:
body: [Object: null prototype] {
'{"email":"literak#seznam.cz","password":"centrum"}': ''
}
undefined
When I added Axios options, the chrome shows an error for this request but there is nothing on server.
const options = {
headers: {
'Content-Type': 'application/json',
},
};
const axiosResponse = await axios.post(`${API_ENDPOINT}/authorizeUser`, JSON.stringify({
email: payload.email,
password: payload.password,
}), options);
Chrome request looks strange, there is no response section, request headers are very different and I can see in the Timing tab, that the request stalled.
If I remove stringify function, it behaves the same:
const axiosResponse = await axios.post(`${API_ENDPOINT}/authorizeUser`, {
email: payload.email,
password: payload.password,
}, options);
And same trouble without stringify and custom options:
const axiosResponse = await axios.post(`${API_ENDPOINT}/authorizeUser`, {
email: payload.email,
password: payload.password,
}, options);
Only the first variant with stringify and without options reaches the server. I use Postman the request is processed by the server.
logs:
body: { email: 'literak#seznam.cz', password: 'centrum' }
}
literak#seznam.cz
Axios is the latest 0.19.2 version. Chrome is up to date as well. I have no idea why the other combinations do not reach the server. It looks like Chrome received a correct request. What can be wrong? It drives me crazy.
Update: console
Error: Network Error
at createError (createError.js?2d83:16)
at XMLHttpRequest.handleError (xhr.js?b50d:83)
CORS in nanoexpress is apparently known bug:
const corsPerRoute = cors();
app.options('/my-route', corsPerRoute, () => {});
app.get('/my-route', corsPerRoute, (req, res) => {
res.send('this route protected by your cors per-route config');
});
I have tried to send, with Google API and Axios, a new email:
async SendMail (req, res) {
try {
const email = `From: ${req.body.sender}\r\n` + `To: ${req.body.receiver}\r\n` + `Subject: ${req.body.subject}\r\n\r\n` + req.body.message
const response = await axios.post(`https://www.googleapis.com/upload/gmail/v1/users/${req.body.userId}/messages/send`, email, {headers: {Authorization: `Bearer ${req.body.token}`, 'content-type': 'message/rfc822'}})
res.status(200).send({data: response.data, status: 'ok'})
} catch(err) {
console.log('error => ', err)
res.status(404).send({
error: 'Error for the recuperation of Google info'
})
}
}
It tells me I am unauthorised but I have added the correct scopes.
error: {
response: {
status: 401,
statusText: 'Forbidden',
...
}
}
The accessToken is working I have done a call with a get with it and it worked pretty fine.
This is my scope: https://mail.google.com/
I am having an issue with a route in my backend where res.status().send() will only send the client the status code, but it will not send the client the object located inside of send().
Here is my code (redacted all code but the problem for brevity):
exports.user_signup = (req, res) => {
const { body } = req;
const { companyName, password, email } = body;
User.find({ email: email }, (err, previousUsers) => {
if (err) {
return res.status(400).send({
message: "There was an issue signing up."
});
} else if (previousUsers.length > 0) {
return res.status(403).send({
message: "Records show this email is linked to another account."
});
}
}
When I make my fetch request from the client, the response only returns the status code from the server, but nowhere in the response is the object in the send() method on the server. Just spitballing, I threw res.status(200).json(object) at it to send the object as json to no avail.
Here is my `fetch request from the client:
fetch("http://localhost:3000/users/accounts/", {
method: "post",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify(userData)
}).then(response => console.log(response));
}
To show what response I am getting, I purposely posted some form data from the client to the route that would throw the 403 error, and this is the response I get in the browser console:
Response {type: "basic", url: "http://localhost:3000/users/accounts/", redirected: false, status: 403, ok: false, …}
So I am able to successfully send the status back from the route to the client, however I can not for the life of me figure out why send() does not send the object along with it.
The body of the response that comes back from fetch() is a ReadableStream. You need to process it to turn it into something usable. Normally you would call response.json() to parse it as a JSON object:
fetch("http://localhost:3000/users/accounts/", {
method: "post",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify(userData)
})
.then(response => response.json())
.then(response => console.log(response));
}