When sending file over to server, req.body is "{}" [duplicate] - javascript

This question already has answers here:
Node/Express file upload
(11 answers)
How do I POST with multipart form data using fetch?
(3 answers)
Closed 11 hours ago.
I am trying to send a file to my express server to be saved.
On the front end, when I call console.log(_("#fileElem2").files[0]), I receive something like this:
Front End:
<input type="file" id="fileElem2">
_("#fileElem2").addEventListener("change", (e) => {
console.log(_("#fileElem2").files[0])
fetch('/uploadFile', {
method: 'POST',
body: _("#fileElem2").files[0]
})
})
function _(query) {
return document.querySelector(query);
}
Backend (server):
const express = require('express')
const app = express()
require('dotenv').config()
const http = require('http')
const port = process.env['port']
const path = require("path")
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server);
const helmet = require("helmet");
app.set('socketio', io);
app.post("/uploadFile", (req, res) => {
console.log(req.body);
})
app.use(express.static('static'))
app.use(express.json())
app.use(helmet())
app.get("/", (req, res) => {
res.sendFile(path.join(__dirname, "html/index.html"));
})
server.listen(port, () => {
console.log(`Server running on ${port}!`)
})
io.on("connection", (socket) => {
// socketio stuff
})
When the console.log(req.body); runs, I only recieve {} in the console.
Am I supposed to be using req.body to recieve the file, or is there some other function?

Related

access localhost with smartphone and get no response from the server

website works via localhost on pc
access with smartphone to localhost via ip too (I receive html, css and js for client)
when I click the button, a "hi" is also added but function "search()" is not executed
but when I enter the url http://localhost:3000/users I get the "hi1"
What do i have to do to make this work?
Client Side
const button = document.querySelector("button");
button.addEventListener("click", () => {
document.getElementById("imageDiv").innerHTML = "Hi";//this work
search();//this not work
});
async function search(){
await fetch("http://localhost:3000/users")
.then(response => response.json())
.then(response => {
var image;
image = JSON.parse(JSON.stringify(Object.assign({},response)));
document.getElementById("imageDiv").innerHTML = response;
})};
Server Side
const express = require('express');
const bodyParser = require('body-parser');
const path = require("path"); // window or mac
const cors = require('cors');
const app = express();
const port = 3000;
//var word = "";
//const router = express.Router();
// configure CORS to avoid CORS errors
app.use(cors());
// configure body parser so we can read req.body
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static('./client'));
app.get('/', (req, res) => {
res.sendFile("./index.html");
});
app.get("/users", (req, res) => {
datafiles = ["hi1"];
res.json(datafiles);
res.status(200);
});
app.listen(port, () => {
console.log(`Server listening on http://localhost:${port}`);
});

Empty body Api rest express node js

I'm trying to make an API using express in nodejs.
This api should get a request with a photo and post that photo to firebase storage.
The main problem is that for some reason the body of the requests I send are empty.
This is the code for the server:
const express = require("express");
const morgan = require("morgan")
const cors = require('cors')
const app = express();
// Settings
app.set('port', process.env.PORT || 3000)
app.set('json spaces', 4)
// middleware
app.use(morgan("dev"))
app.use(express.json())
app.use(express.urlencoded({extended: true}))
app.use(cors({origin: "http://localhost:3001"}))
// routes
app.use(require("./routes/index"))
app.listen(app.get('port'), () => {
console.log("Server using port " + app.get('port'));
});
Routes
const { Router } = require('express')
const router = Router()
router.post('/postImage', async (req, res) => {
try {
const image = req.body
console.log(image) // Here I only get an epty object "{}"
return res.status(200).json(image)
}
catch(error) {
console.log(error)
return res.status(500).json({error})
}
})
module.exports = router
Client side
const postImage = async (image) => {
console.log(image) // Here I get the image data
const response = await fetch("http://localhost:3000/postImage", {
method: "POST",
body: {message: "image"}
})
const data = await response.json()
}
I've tried using body-parser but it seems to be deprecated
you have to send an image from the front end in formData.
const data = new FormData();
data.append('myFile', 'Image Upload');
In back end use multer to upload file to server.
first install multer by : npm i multer
const multer = require("multer");
//Configuration for Multer
const upload = multer({ dest: "public/files" });
app.post("/api/uploadFile", upload.single("myFile"), (req, res) => {
// Stuff to be added later
console.log(req.file);
});
Here is a proper Guide to upload file using multer express js

Put request req.body is empty

As all my requests are working fine, I have a problem with the put. req.body stays empty and then gives that error :
errmsg: "'$set' is empty. You must specify a field like so: {$set:
{: ...}}"
PUT :
router.put('/books/:name', (req, res, next) => {
const localdb = db.client.db(process.env.DB_NAME);
const collection = localdb.collection(process.env.COLL_BOOKS);
collection.replaceOne(
{ "name": req.params.name },
{ $set: req.body },
function (err) {
if (err) throw err
res.status(201).send(true);
});
App.js
const express = require('express'),
app = express();
os = require('os');
const bodyParser = require('body-parser');
const cors = require('cors');
const router = require('./router.js')
require('dotenv').config()
app.use(cors());
app.use(bodyParser.json());
app.use('/api/v1', router);
const port = (process.env.PORT || '3001');
let server = app.listen(port, os.hostname(), () => {
let host = server.address().address,
port = server.address().port;
console.log("Example app listening at http://%s:%s", host, port);
});
axios request :
updateItem = newBook => {
Axios.put(process.env.REACT_APP_API_PATH_BOOKS + `${newBook.name}`, newBook)
.then(res => {
this.setState({ newBook: res.data });
this.props.history.push('/admin');
})
.catch(err => console.log(err));
}
I don't understand what I am doing wrong
Make sure you don't have any middlware stripping or incorrectly parsing the body. For instance, you may have a JSON body parser, and not be sending JSON data with JSON application headers.
Can you give a bit of context, in code, for how you are making the put request and also the result of logging the req in a pastebin?

Getting error 405 when sending request on express route in next js

I create routes on Express js in Next js. When i deployed on hosting and sent request on route i getting error 405, but when i do same on localhost everything all right.
I cant understand that is this?
const express = require('express')
const next = require('next')
const bodyParser = require('body-parser')
const PORT = process.env.PORT || 3000
const dev = process.env.NODE_ENV !== 'production' //true false
const nextApp = next({ dev })
const handle = nextApp.getRequestHandler() //part of next config
nextApp.prepare().then(() => {
const app = express()
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const apiRoutes = require("./routes");
app.use('/api', apiRoutes)
app.get('*', (req,res) => {
console.log('asdfasdfasdfd')
return handle(req,res)
})
app.listen(PORT, err => {
if (err) throw err;
console.log(`ready at http://localhost:${PORT}`)
})
})
I think your express config has problem.
your express server must be like this:
const express = require('express')
const next = require('next')
const handler = routes.getRequestHandler(app)
const app = next({ dir: '.', dev })
app.prepare().then(() => {
const server = express()
server.post('/api', (req, res) => {
handler(req, res, req.url)
)
server.get('*', (req, res) => {
handler(req, res, req.url)
})
}
check the code for server.get and server.post or other http methods.
Error 405 tells that the method is not allowed.
Vercel can't use custom server with next js
https://github.com/vercel/next.js/discussions/13306

cannot GET / when serving Angular app using express and nodejs

I am trying to serve an angular app using nodejs. But i get this error
"Cannot GET /" in the body of the page. I tried a number of things but still this does not work. do you folks have any suggestion?
const express = require('express')
const app = express()
var cors = require('cors')
const bodyParser = require('body-parser')
const fileUpload = require('express-fileupload')
const couchDb = require('./modules/couchDb')
const db = couchDb.db
const schedules = require('./modules/schedules')
const stations = require('./modules/stations')
const testConfigs = require('./modules/testConfigs')
app.use(cors())
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: true}))
app.use(fileUpload())
app.listen(5000, () => console.log('Listening on port 5000'))
////////////////////////////////////////
// View
////////////////////////////////////////
const viewOptions = { include_docs: true }
app.route('/api/schedules').get((req, res) => {
couchDb.getType('schedule', viewOptions).then(docs => {
res.send(docs)
}).catch(err => {
console.log(err)
res.send({})
})
})
app.route('/api/stations').get((req, res) => {
couchDb.getType('station', viewOptions).then(docs => {
res.send(docs)
}).catch(err => {
console.log(err)
res.send({})
})
})
app.route('/api/tests').get((req, res) => {
couchDb.getType('testConfig', viewOptions).then(docs => {
res.send(docs)
}).catch(err => {
console.log(err)
res.send({})
})
})
you are missing your routes e.g
app.get('/', function (req, res) {
res.send('hello world')
})
or you need to include your all routes through middle ware.
You are getting that error because you are not declaring any endpoints or telling the server to serve anything. It is listening on port 5000, but no responses to any urls have been defined. Here is a piece of example code that will resolve your issue.
const express = require('express')
const app = express()
var cors = require('cors')
const bodyParser = require('body-parser')
const fileUpload = require('express-fileupload')
app.use(cors())
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: true}))
app.use(fileUpload())
// This block will make it so that every path on port 5000 responds with "Hello, World!"
app.get('*', (req, res) => {
res.status(200).send("Hello, World!");
});
app.listen(5000, () => console.log('Listening on port 5000'))
This will make it respond with basic text, if you want to serve an angular application, you will need to look into serving static content from express: https://expressjs.com/en/starter/static-files.html
You have to use a routing middleware and map your modules to the required modules.Also make sure your modules are mounted in router instance.
Something like
const express = require('express')
const app = express()
var cors = require('cors')
const bodyParser = require('body-parser')
const fileUpload = require('express-fileupload')
const couchDb = require('./modules/couchDb')
const db = couchDb.db
const schedules = require('./modules/schedules')
const stations = require('./modules/stations')
const testConfigs = require('./modules/testConfigs')
app.use(cors())
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: true}))
app.use(fileUpload())
//All requests with /schedules will go to './modules/schedules'
app.use('/schedules', schedules);
app.use('/stations', stations);
app.listen(5000, () => console.log('Listening on port 5000'))
your ./modules/station should look like
var express = require('express')
var router = express.Router()
router.get('/', function (req, res) {
res.send('You are in /station')
})
router.get('/new', function (req, res) {
res.send('You are in /station/new')
})
module.exports = router
For more : https://expressjs.com/en/guide/routing.html

Categories