Axios - How to fix - POST URL net::ERR_CONNECTION_RESET - node.js

How to fix this error message?
[xhr.js?b50d:178 POST http://localhost:3000/editor/add net::ERR_CONNECTION_RESET][1]
It works and append data, but I get this error message...
My API looks like this:
app.js
app.post('/editor/add', function (req, res) {
let articleData;
let textData;
let article = {
title: req.body.title,
content: req.body.content
}
fs.readFile(urlPath, 'utf8', (err, data) => {
if (err) {
console.log('readfile => ' + err);
} else {
articleData = JSON.parse(data);
articleData[article.title] = article.content;
textData = JSON.stringify(articleData, null, 2);
fs.writeFile(urlPath, textData, 'utf8', (err) => {
if (err) {
console.log('write file => ' + err);
} else {
console.log('Finished writing');
}
});
}
});
});
And my Axios POST method looks like this.
editor.vue
submitEditor: function() {
var self = this;
self.$axios({
headers: {
"Content-Type": "application/json"
},
method: "post",
url: "http://localhost:3000/editor/add",
data: {
title: "test5",
content: self.html
}
})
.then(res => {
console.log(res);
})
.catch(error => {
if (!error.response) {
// network error
this.errorStatus = "Error: Network Error";
} else {
this.errorStatus = error.response.data.message;
}
});
}
I use Vue/cli, I separate my client code and my server code. They are on a separate folder. I put Vue/cli in my client folder, and express.js in my server folder.
Thank you in advance!

Try sending a response from your route:
fs.writeFile(urlPath, textData, 'utf8', (err) => {
if (err) {
console.log('write file => ' + err);
} else {
console.log('Finished writing');
res.json({ msg: 'success' }); // send the client something
}
});

Related

How can I get a clean response from POST request and save it in a json file

I have the following code for POST request with nodejs and hapi framework:
server.route({
method: "POST",
path: "/newdata",
config: {
validate: {
query: Joi.object({
alert: Joi.boolean().default(true)
})
}
},
handler: (request, h) => {
fs.readFile('./data.json', (err, data) => {
if (err) {
console.log(`Error reading file: ${err}`);
} else {
const object = JSON.parse(data);
object.push(JSON.stringify(request.payload));
console.log(object)
fs.writeFileSync('./data.json', JSON.stringify(object, null, 4), (err) => {
if (err) {
console.log(`Error writing file: ${err}`);
}
});
}
});
return request.payload;
}
});
The response which a get looks like this : "{\"name\":\"Johny Crumpy\",\"corp\":\"USA\"}". How can I save it in the json file without "" everywhere and . In the json file it should like like this: {
"name": "Steve Ballmer",
"corp": "Microsoft"
},
You are getting these extra quotes because you are doing JSON.strigify twice. Try this.
handler: (request, h) => {
fs.readFile('./data.json', (err, data) => {
if (err) {
console.log(`Error reading file: ${err}`);
} else {
const object = JSON.parse(data);
object.push(request.payload);
console.log(object)
fs.writeFileSync('./data.json', JSON.stringify(object, null, 4), (err) => {
if (err) {
console.log(`Error writing file: ${err}`);
}
});
}
});
return request.payload;
}

Sending webm blob to nodejs and saving it on the server

I'm having troubles saving an incoming webm blob to the server. I'm using react-video-recorder on NextJS like this:
<VideoRecorder
onRecordingComplete={(videoBlob) => {
// Do something with the video...
fetch("/api/video",
method: "post",
body: videoBlob,
})
.then(function (response) {
console.log("done");
return response;
})
.catch(function (err) {
console.log('error', err);
});
console.log(url);
// output: blob:http://localhost:3000/99a5b711-f3d5-481d-9e04-8981d1be3727
console.log(videoBlob);
// output BlobĀ {size: 307028, type: "video/webm;codecs="vp8,opus""}
}}
/>
On the api side I'm trying to save the file like this. It does save something, but is only the first chunk or buffer. How can I capture and write the file to my server?
export default async (req, res) => {
fs.writeFile('test.webm', req.body, function (err) {
if (err) return console.log(err);
console.log('video saved');
} );
}
I did that task by doing this.
I saved the recordingChunks/Video blob to a state and then sent it to the Nodejs server from Reactjs Frontend
FrontEnd code:-
const blob = new Blob(context.data.recordedChunks, {
type: "video/webm",
});
const fd = new FormData()
fd.append('video', blob)
axios.post(`${process.env.REACT_APP_BASE_URL}/video/blob_video`, fd)
.then((res) => console.log(res.data))
.catch((err) => console.log(err))
Backend code:-
router.post('/blob_video', async (req, res) => {
try {
if (req.files.video !== undefined) {
const video = req.files.video // this is your file do what ever you want with it
const videoname = Date.now() + req.files.video.name + ".webm"
video.mv(`${__dirname}/../your_path/${videoname}`, err => {
if (err) {
console.log(err)
return res.json({ err })
}
})
}
res.json(req.body)
} catch (err) {
res.json({ success: false, err: err, msg: "Server error" })
console.log(err)
}
})
Using express-fileupload to upload a file you can do it with your favourite one.

why I m getting TypeError: Failed to fetch?

I got a fetched error type when trying to send data from a react app .
note that I m using cores.
and it s working fine on localhost with client side and not when hosting it online.
Note : I get result from json when using postman like this :
{
"success":"true",
"ID":"token"
}
this is the back-end code source in expressjs :
router.post("/sickers/user/login/", cors(), (req, res) => {
var values = req.body;
var pass = values.password;
var email = values.email;
if (pass !== null || pass !== "") {
try {
con.query("SELECT Password ,ID FROM `sickers` WHERE Email='" + email + "'", function(err, rows, field) {
if (err) {
console.log(err);
res.send("an error detected try later");
} else {
try {
if (pass == rows[0].Password) {
//create the signed function
jwt.sign(rows[0].ID, "secretkey", (err, token) => {
res.json({ success: "true", ID: token })
})
//session.session( )
} else {
res.json({ success: "false" });
}
} catch {
res.json({ success: "false" });
}
}
});
} catch (e) {
res.json({ success: "false" });
}
}
});
and client method is :
//submit values
const submithandler=async (e)=> {
e.preventDefault();
try{
console.log('start')
await fetch('url/api/sickers/user/login/',{
method:'post',
headers:{
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body:JSON.stringify({
password:password,
email:email
})
})
.then(response =>
{
console.log("response");
response.json().then(data =>
{
console.log(data);
if(data.success=="true")
{
sessionStorage.setItem('ID',data.ID);
window.location.reload();
seterr("");
}
else
{
seterr("try again");
}
});
});
}
catch(e)
{
console.log(e)
}
}
do I miss something here?
thanks in advance.
I solved this before by adding cores to .htaccess on server , or hosting the full project with it's back and front ends into the same server.

HapiJs File Upload : 500 Internal Server Error while uploading large files, Reply never reaches back to the ccaller

We are using IISNODE to host our node application written using "hapi": "^16.5.2", the Route is pasted below
{
method: 'POST',
path: '/xxxx/xxxx/xxxx/Upload/',
config: {
auth: { strategies: ['simple'] },
handler: uploadHandler.Upload,
plugins: {
'hapi-swagger': {
responses: fileHTTPStatus,
payloadType: 'form'
},
disinfect: {
disinfectQuery: false,
disinfectParams: false,
disinfectPayload: false
},
policies: ['MethodAudit']
},
tags: ['api'],
validate: {
payload: {
file: Joi.any().meta({ swaggerType: 'file' }).required().description('file')
}
},
payload: {
maxBytes: 209715200,
parse: true,
allow: 'multipart/form-data',
output: 'stream'
},
cors: {
origin: ['*'],
additionalHeaders: ['cache-control', 'x-requested-with', 'accept', 'authorization', 'content-type', 'if-none-match', 'origin', 'Accept-language']
}
}
}
uploadHandler.Upload Method looks like this:
function Upload (request, reply) {
if (request.payload) {
var data = request.payload;
if (data.file) {
var originalName = data.file.hapi.filename;
var path = rootDocPath + originalName; //rootDocPath is our common location
var file = fs.createWriteStream(path);
file.on('error', function (err) {
console.error(err)
});
data.file.pipe(file);
file.on('end', function() {
console.log('file ended');
});
file.on('finish', function() {
console.log('file finished');
});
data.file.on('end', function(err) {
console.log('data.file ended');
});
file.on('close', function(err) {
reply('Uploaded');
});
} else {
reply('no file')
}
} else {
reply('no payload')
}
}
The response which we get is IIS 8.5 Detailed Error - 500.1013 - Internal Server Error
While debugging we could see that reply("Uploaded") is being executed but the response is never received by the caller.
This behaviour is only exhibited with larger files (more than 1.9
MB), for smaller files it works 100%
Maybe there is something going on in your stream pipe.
Here is my dump uploader which uses promises I never had a single problem with it. Maybe you can compare with your process.
const fileUploader = function (file, targetPath) {
if (!file) throw new Error('no file');
const fileStream = fs.createWriteStream(targetPath);
return new Promise((resolve, reject) => {
file.on('error', function (err) {
reject(err);
});
file.pipe(fileStream);
file.on('end', function (err) {
resolve({
fieldname: file.hapi.name,
originalname: file.hapi.filename,
mimetype: file.hapi.headers['content-type'],
targetPath,
size: fs.statSync(targetPath).size,
});
})
})
};
// usage
const filePath = await helpers.fileUploader(request.payload.data, targetPath);
The fix that worked for me was to set the request payload to null before sending a response back to the caller. Seems like if the request payload size is too large the service is unable to respond. Please see the fix below (look for the comment This is the FIX):
function Upload (request, reply) {
if (request.payload) {
var data = request.payload;
if (data.file) {
var originalName = data.file.hapi.filename;
var path = rootDocPath + originalName; //rootDocPath is our common location
var file = fs.createWriteStream(path);
file.on('error', function (err) {
console.error(err)
});
data.file.pipe(file);
file.on('end', function() {
console.log('file ended');
});
file.on('finish', function() {
console.log('file finished');
});
data.file.on('end', function(err) {
console.log('data.file ended');
});
file.on('close', function(err) {
request.payload.file = null; /*This is the FIX*/
reply('Uploaded');
});
} else {
reply('no file')
}
} else {
reply('no payload')
}
}

Node JS LDAP Auth User

I am creating a login authentication page, where a user would input there active directory username and password and using NodeJS I would check to see if it's valid, but I keep getting
[Error: LDAP Error Bad search filter]
or
[Error: Search returned != 1 results]
When I'm trying to search for the username and password, my code is below:
I'm using: https://github.com/jeremycx/node-LDAP, let's say that the user entered a username of hhill
var ldap = require('LDAP');
var ldapServer = new ldap({ uri: 'ldap://batman.lan', version: 3});
ldapServer.open(function(error) {
if(error) {
throw new Error('Cant not connect');
} else {
console.log('---- connected to ldap ----');
username = '(cn='+username+')';
ldapServer.findandbind({
base: 'ou=users,ou=compton,dc=batman,dc=lan',
filter: username,
password: password
}, function(error, data) {
if(error){
console.log(error);
} else {
console.log('---- verified user ----');
}
});
}
});
Does anyone have any suggestions on what I'm doing wrong?
UPDATE
Here is the solution I came up with if anyone ever needs it, with the help of the answer below
var username = request.param('username');
var password = request.param('password');
var ldap = require('ldapjs');
ldap.Attribute.settings.guid_format = ldap.GUID_FORMAT_B;
var client = ldap.createClient({
url: 'ldap://batman.com/cn='+username+', ou=users, ou=compton, dc=batman, dc=com',
timeout: 5000,
connectTimeout: 10000
});
var opts = {
filter: '(&(objectclass=user)(samaccountname='+username+'))',
scope: 'sub',
attributes: ['objectGUID']
};
console.log('--- going to try to connect user ---');
try {
client.bind(username, password, function (error) {
if(error){
console.log(error.message);
client.unbind(function(error) {if(error){console.log(error.message);} else{console.log('client disconnected');}});
} else {
console.log('connected');
client.search('ou=users, ou=compton, dc=batman, dc=com', opts, function(error, search) {
console.log('Searching.....');
search.on('searchEntry', function(entry) {
if(entry.object){
console.log('entry: %j ' + JSON.stringify(entry.object));
}
});
search.on('error', function(error) {
console.error('error: ' + error.message);
});
client.unbind(function(error) {if(error){console.log(error.message);} else{console.log('client disconnected');}});
});
}
});
} catch(error){
console.log(error);
client.unbind(function(error) {if(error){console.log(error.message);} else{console.log('client disconnected');}});
}
In this case, you need ldapClient rather than ldapServer, this is the example code from the official doc:
var ldap = require('ldapjs');
ldap.Attribute.settings.guid_format = ldap.GUID_FORMAT_B;
var client = ldap.createClient({
url: 'ldap://127.0.0.1/CN=test,OU=Development,DC=Home'
});
var opts = {
filter: '(objectclass=user)',
scope: 'sub',
attributes: ['objectGUID']
};
client.bind('username', 'password', function (err) {
client.search('CN=test,OU=Development,DC=Home', opts, function (err, search) {
search.on('searchEntry', function (entry) {
var user = entry.object;
console.log(user.objectGUID);
});
});
});
#Sukh Thank you for posting your UPDATE solution; however, there is a problem with the code you posted in your UPDATE. While it works for simple cases, with larger queries, you will find you are unbinding before the results have been output. The solution for me was to move your unbinds into the search.on functions.
Here is an edit of your UPDATE:
var ldap = require('ldapjs');
ldap.Attribute.settings.guid_format = ldap.GUID_FORMAT_B;
var client = ldap.createClient({
url: 'ldap://batman.com/cn='+username+', ou=users, ou=compton, dc=batman, dc=com',
timeout: 5000,
connectTimeout: 10000
});
var opts = {
filter: '(&(objectclass=user)(samaccountname='+username+'))',
scope: 'sub',
//attributes: ['objectGUID']
// This attribute list is what broke your solution
attributes: ['objectGUID','sAMAccountName','cn','mail','manager','memberOf']
};
console.log('--- going to try to connect user ---');
try {
client.bind(username, password, function (error) {
if(error){
console.log(error.message);
client.unbind(function(error) {if(error){console.log(error.message);} else{console.log('client disconnected');}});
} else {
console.log('connected');
client.search('ou=users, ou=compton, dc=batman, dc=com', opts, function(error, search) {
console.log('Searching.....');
search.on('searchEntry', function(entry) {
if(entry.object){
console.log('entry: %j ' + JSON.stringify(entry.object));
}
client.unbind(function(error) {if(error){console.log(error.message);} else{console.log('client disconnected');}});
});
search.on('error', function(error) {
console.error('error: ' + error.message);
client.unbind(function(error) {if(error){console.log(error.message);} else{console.log('client disconnected');}});
});
// don't do this here
//client.unbind(function(error) {if(error){console.log(error.message);} else{console.log('client disconnected');}});
});
}
});
} catch(error){
console.log(error);
client.unbind(function(error) {if(error){console.log(error.message);} else{console.log('client disconnected');}});
}
At least this is what I discovered when using your solution with Active Directory searches. memberOf returns A LOT of entries in my use case and the unbinds were being done prematurely, so I was getting the following error:
error: 1__ldap://my.domain.com/,OU=Employees,OU=Accounts,DC=my,DC=domain,DC=com closed
client disconnected
Suggestions
1.Don't use ldapauth-fork (Huge hanging issue, if we hit multiple requests then after some time library gets unresponsive and doesn't return anything.)
2.Don't use passport-ldapauth (Internally calls ldapauth-fork)
We can use ldapjs, which has easy implementation and is based on event driven approach.
Below nodejs code explain complete solution for ldap auth and search.
JS code
const ldap = require('ldapjs');
let client
// unbind after completion of process
function closeConnection() {
console.log('closeConnection')
client.unbind(err => {
console.log('unbind error', err)
});
}
function search() {
const searchOptions = {
filter: '(uid=yourSearchText)', // search text
scope: 'sub'
};
return new Promise((resolve, reject) => {
client.search('ou=consultants,' + 'ou="Your OU",ou=yourOu,dc=yourDc,dc=com', searchOptions, (err, res) => {
res.on('searchEntry', entry => {
console.log('searchEntry', entry.object);
resolve(entry.object)
});
res.on('searchReference', referral => {
console.log('referral: ' + referral.uris.join());
resolve(referral.uris.join())
});
res.on('error', err => {
console.error('search error: ' + err.message);
reject(err)
});
res.on('end', result => {
console.log('If not found', result);
reject({ message:'User not found'})
});
});
})
}
function authenticate() {
const server = 'ldap server ip';
client = ldap.createClient({
url: `ldap://${server}`
});
return new Promise((resolve, reject) => {
client.bind('cn=yourcn,dc=yourdc,dc=com', 'sortedSolutions', err => {
if (err) {
reject(err)
}
resolve('Authenticated successfully')
});
})
}
function start(req, res) {
let searchResponseData
authenticate()
.then(authenticateResponse => {
console.log('authenticateResponse', authenticateResponse)
return search()
})
.then(searchResponse => {
console.log('searchResponsesearchResponse', searchResponse)
searchResponseData = searchResponse
return closeConnection()
})
.then(closeConnectionResponse => {
console.log('ldap connection closed', closeConnectionResponse)
res.status(200).send(searchResponseData)
})
.catch(error => {
console.log('catch error', error)
res.status(400).send(error)
})
}
module.exports.start = start
// We can use same code with no authentication, Just pass '' to bind function client.bind('', '', err => { //same as above })

Resources