nodeJS upload issue proxy error 502 with PM2 - node.js

I have an express nodeJS application that uploads and XLSX file and displays it content. The code in app.js is as following :
var express = require('express')
var multer = require('multer')
var app = express()
var upload = multer({ dest: 'uploads/' })
//Upload XLSX file
app.post('/upload', upload.single('xlsx_file'), function (req, res, next) {
if (req.file === undefined) {
console.log("Error");
} else {
var mimetype = req.file["mimetype"];
if (mimetype === "application/vnd.ms-excel.12" || mimetype === "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") {
var path = req.file["path"];
readXLSX(path, function (response) {
console.log(response);
});
} else {
console.log("Only Excel (2007) xslx files are allowed!</strong></p>");
}
}
});
I'm using PM2 advanced process manager to run my application for ever, when I do pm2 start all and try to upload a file I get :
Proxy Error
The proxy server received an invalid response from an upstream server.
The proxy server could not handle the request POST /upload.
Reason: Error reading from remote server
Additionally, a 502 Bad Gateway error was encountered while trying to use an ErrorDocument to handle the request.
when I run the app in debug mode with DEBUG=myapp:* npm start the upload works fine.
Any idea why this is happening?
Thanks

Related

Node JS post API endpoint not recognized in front end

I'm trying to make a post request using appwrite SDK in Node JS express and Vue JS. The SDK requires me to create an api post request to create new storage bucket in appwrite. The DOCs for this particular request isn't explaining really how to create the api in node JS express. I'm really new to Node JS and I already succeeded at creating get request but whenever I create the post request I get 404 not found error.
Node JS express file (server.js):
In this file there is get users request API which works perfectly fine.
And there is create bucket post request which when being called in frontend it comes back with a 404
const express = require("express");
const path = require("path");
const app = express(),
bodyParser = require("body-parser");
port = 3080;
// Init SDK
const sdk = require("node-appwrite");
let client = new sdk.Client();
let users = new sdk.Users(client);
let storage = new sdk.Storage(client);
client
.setEndpoint("http://localhost/v1") // Your API Endpoint
.setProject("tailwinder") // Your project ID
.setKey(
"Secrer Key!"
); // Your secret API key
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, "../appwrite-app/build")));
//This get request works fine
//get user by ID
app.get("/v1/users/:id", (req, res) => {
let promise = users.get(req.params.id);
promise.then(
function (response) {
res.json(response);
},
function (error) {
console.log(error);
}
);
});
//This one isn't recognised in frontend
app.post("/v1/storage/buckets", function (req, res) {
let promise = storage.createBucket("bucket_id", "bucket_name", "file");
promise.then(
function (response) {
res.json(response);
},
function (error) {
console.log(error);
}
);
});
app.listen(port, () => {
console.log(`Server listening on the port::${port}`);
});
bucketsServices.js:
Here I'm using fetch post request to the api endpoint but it's not working.
export async function createBucket() {
const response = await fetch("/v1/storage/buckets", {
method: "POST",
});
return await response.json();
}
Addcomponent.vue:
Here I'm calling out the createBucket function from vue js file
bucketTesting() {
createBucket().then((response) => {
console.log(response);
});
},
The error which I assume it means that it's not reading my node js express post API:
bucketsService.js?993b:2 POST http://localhost:8080/v1/storage/buckets 404 (Not Found)
Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0
A screenshot of the same error:
Something is missing here and I can't really figure it out.
You are making request to localhost:8080 meanwhile your server is running at localhost:3080
I believe your vue is running at port 8080 that's why /v1/storage/buckets gets prefixed by localhost:8080
Try to provide full URL while making request
export async function createBucket() {
const response = await fetch("localhost:3080/v1/storage/buckets", {
method: "POST",
});
return await response.json();
}
Better way might be to add proxy to automatically redirect request to correct URL, but this should work for now. This article might help with how to setup proxy in vue

How to upload file from nodeJS to nodeJS

I have 2 nodeJS services and I would want to upload file in a dir, from one NodeJS (backend) to another NodeJS(backend). The receiver nodeJS is an express app.
Looking for some working code sample.
PS: Couldn't find any code samples in search, since everywhere it was Multer from client to server uploads that receives multipart/form-data.
Uploading file using POST request in Node.js
Receive the file first as you correctly said using Multer. Then, you may either save the file to a temporary directory before uploading it again or just send the file as-is.
You need to setup a server running with Multer on the 2nd server that wishes to receive the file.
const express = require('express');
const app = express();
const upload = multer({ dest: 'files/' });
app.post('/upload', upload.single('file'), (req, res) => {
res.sendStatus(200);
});
app.listen(3001);
Then on the server you wish to send the file from, do something like this:
const request = require('request');
const req = request.post('localhost:3001/upload', (err, res, body) => {
if (err) throw new Error(err);
if (res && res.statusCode == 200) {
console.log('Success');
} else {
console.log('Error');
};
});
const form = req.form();
form.append('file', fs.createReadStream('./location/to/file'));

Node.js - static files are getting replaced with HTML code

Problem
I just started out with Node.js my plan was to first set up a Server with some basic HTML and static files(css,js).
But when i try to Serve the static files with express.js or even without express the js/css code is getting replaced from my index.html code. Without Node.js everything seems to work fine i even tried it with flask in python which worked fine too.
Are there any common reasons for this?
Node.js code
var http = require("http");
var fs = require("fs");
var express = require("express");
var app = express();
app.use("/", express.static("public"));
http
.createServer(function(req, res) {
fs.readFile("index.html", function(err, data) {
if (err) {
res.writeHead(404, { "Content-Type": "text/html" });
return res.end("404 Not Found");
}
res.writeHead(200, { "Content-Type": "text/html" });
res.write(data);
return res.end();
});
})
.listen(8080);
Pictures
So even though you are using express to serve static files, you are not using express as server instead of that you are making a manual server which serves index.html for EVERY request.
http
.createServer(function(req, res) {
fs.readFile("index.html"....);
})
.listen(8080);
What this code means is create a server, and for each request read the index.html file and serve this
So when the request is http://localhost:8080/css.css it doesn't discriminate.
I would recommend reading about creating servers in node a little more. But the solution is use express as server.
var http = require("http");
var fs = require("fs");
var express = require("express");
var app = express();
app.use("/", express.static("public"));
app.listen(8080, ()=>{
console.log('Server started');
})
This will work just fine GIVEN that index.html IS IN A FOLDER NAMED PUBLIC
From the doc,
For example, use the following code to serve images, CSS files, and
JavaScript files in a directory named public:
app.use(express.static('public'))
Now, you can load the files that are
in the public directory:
Note, if your files are in your project root you can use:
app.use("/", express.static("."));

Setting correct headers for uploading file using Angular and Node

I'm having a headache trying to upload files to a Node server from an Angular 6 app. I have the following route handler in the Node app:
var express = require('express');
var router = express.Router();
// Route for /fileupload
//****************************************************************
// Multer module for uploading files
var multer = require('multer');
// set the directory for the uploads to the uploaded to
var DIR = './uploads/';
var upload = multer({ dest: DIR }).single('cloudImg');
router.post('/', (req, res, next) => {
var path = '';
upload(req, res, function(err) {
console.log('REQ HEADER', req.headers);
if (err) {
// An error occurred when uploading
console.log(err);
return res.status(422).send("an Error occured")
}
// No error occured.
path = req.file.path;
return res.send("Upload Completed for " + path);
});
});
module.exports = router;
I use the multer module for uploading the file. If I call the API from Postman, everything works fine:
But if I send the file from the Angular app, the Node server crashes giving this error: TypeError: Cannot read property 'path' of undefined.
I've realised that Postman sets this content-type header:
'content-type': 'multipart/form-data; boundary=--------------------------719034023986440712074389'
I'm pretty sure that the error happens because the Node server is expecting another type of data and it can't create the req.file object. I know how to set the content-type header, but how could I generate the boundary field? Or, is there any way to tell Angular httpClient methods to autogenerate the header for this case?
Thanks,

Unable to upload a file express(NodeJS)

I was facing this tiny issue in a sample NodeJS application I was creating, that I always receive req.files as undefined even though I am uploading a file via postman.
Here's the code:
import express from 'express';
import http from 'http';
let app = express();
app.post('/', function(req, res) {
let files = req.files;
res.send(files);
})
app.listen(process.env.PORT || 8000, () => {
console.log(`Started on port 8000`);
});
export default app;
And here's how I am sending the file via postman:
But I still get and empty response and also as logging on cmd I get the output as undefined:
Would be greatful if anyone could help.
If you want to upload files, I recommend using multer: https://www.npmjs.com/package/multer
But if you don't want to use multer or bodyparser, you can stream the data:
req.on('data', data => {
console.log(data);
});
You can pipe the stream to write to file. check fs documentation.

Resources