I need to handle some request without content-type as binary file
const app = express();
app.use(bodyParser.raw({type: (req) => !req.headers['content-type'], limit: '500mb' }));
those file can be huge (eg. 500 MB).
I want to read req.body as stream for don't wast memory, but bodyParser.raw() make req.body as Buffer.
How handle req.body as Stream?
You can use stream to handle huge file.
Express http request is a readable stream, you can pipe the request binary to file, but make sure the output is also a writable stream.
Example code:
const fs = require('fs');
const path = require('path');
const express = require('express');
const app = express();
app.post('/', (req, res, next) => {
req.pipe(fs.createWriteStream(path.join('./uploadFiles', Date.now().toString() + '.mp4')));
req.on('end', () => {
res.end('Upload complete');
next();
})
})
app.listen('3000', () => {
console.log('Server listen to port 3000');
})
Related
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
I have been attempting to respond to a client-side request with Node.JS. I have discovered Node JS - call function on server from client javascript, which seems to explain what I want, except that I can't seem to translate it to my program.
Here is the request via POST in index.html:
$.post("/", {data: 'hi'}, function(result){
$("body").html(result);
});
what I was hoping it would do would be write the result of the call, from my server.js (Node):
const express = require('express');
const path = require('path');
const http = require('http');
const fs = require('fs');
function handler(data, app){
if(req.method == "POST"){
app.setHeader('Content-Type', 'text/html');
app.writeHead(200);
app.end(data);
}
}
const BUILDPATH = path.join(__dirname);
const { PORT = 3000 } = process.env;
const app = express();
app.set('port', PORT);
app.use(express.static(BUILDPATH));
app.get('/*', (req, res) => res.sendFile('static/index.html', { root: BUILDPATH }));
const httpServer = http.createServer(app);
httpServer.listen(PORT);
console.info(`🚀 Client Running on: http://localhost:${PORT}`);
try this code:
const express = require('express');
const path = require('path');
const http = require('http');
const fs = require('fs');
function handler(data, app){
if(req.method == "POST"){
app.setHeader('Content-Type', 'text/html');
app.writeHead(200);
app.end(data);
}
}
const BUILDPATH = path.join(__dirname);
const { PORT = 3000 } = process.env;
const app = express();
app.set('port', PORT);
app.use(express.static(BUILDPATH));
app.get('/', (req, res) => {
res
// best practice is to always return an status code
.status(200)
// just return an json object
.json({"msg": "ok, it all works just fine"})
});
const httpServer = http.createServer(app);
httpServer.listen(PORT);
console.info(`🚀 Client Running on: http://localhost:${PORT}`);
The issue is, is that the only route your Node server listens to is the one you define with /*. As you can see, that route returns your index.html file to the client. You did not specify a route that listens for a request that comes from the client.
To solve the issue, you will have to define a route that listens on a specific route for the request you are trying to make from your client.
I see you are using ExpressJS. here is the documentation on writing routes.
may be its dumb question but I can't find answer yet. :(
I made app using create-react-app, and server file:
server.js
const express = require('express');
const bodyParser = require('body-parser');
const fs = require('fs');
const path = require('path');
const PORT = process.env.PORT || 3000;
const app = express();
const p = path.parse(__dirname);
app.use(express.static('public'));
app.get('/', (req, res) => {
const filePath = path.join(p.dir, 'src', 'index.js');
fs.readFile(filePath, {encoding: 'utf-8'},(err, data) => {
if (err) {
throw err;
}
res.send(data);
});
});
app.listen(PORT, () => {
console.log(`Started at port ${PORT}`);
});
tryied to read index.js file from app src directory but all i got in browser is plain text. I can only run static files from public directory. What i did wrong and how should i run js files of react app using express in node?
You need to send the index.html file that is built by react. A browser can only open a web page from a html file.
You need to first build your react app using npm run build
Then serve it with express with something like
app.get('*', (req,res) => {
res.sendFile('/build/index.html'); // wherever react creates the index.html
});
To give you a basic idea on express,
const express = require('express')
const app = express()
app.get('', (req, res) => {
res.render('index') // index is an html file or a template (ejs, hbs, etc..)
})
// You can't directly send js files
app.get('/info', (req, res) => {
res.render('info', {
title: 'info page',
message: 'welcome to the info page'
})
})
// You can't directly send js files
app.listen(3000, () => {
console.log('Server is up on port 3000.')
})
If you want to send json
const leaderboardHistory = require("relativepath/leaderboardHistory.json")
app.get("/leaderboardhistory", function(req, res){
res.render("leaderboardhistory", {leaderboardHistory : leaderboardHistory});
});
I am trying to download array of objects in .csv format. below is the code snippet which converts an array to .csv and get stored in the file file.csv.
let downloadHelper = function(records){
let csvwriter = require('csv-writer');
createCsvWriter = csvwriter.createObjectCsvWriter;
const csvWriter = createCsvWriter({
path: './file.csv'
csvWriter.writeRecords(records).then(() => {
console.log('Done');
});
}
I need to download the file.csv to my local. tried using requests, didn't help as it is accepting only http requests. no clue, how to proceed..... Please help
You did not provide us a lot of information. But with Express you could do:
app.get("/", (req, res) => {
res.download("./file.csv", "your-custom-name.csv");
});
If this does not help you, please provide more info about the context, framework you are using and what front.
Thank you
For example, you can use Express like this:
// Libs
const express = require('express');
const http = require('http');
const path = require('path');
// Setup
const port = 8080;
const app = express();
const httpServer = http.createServer(app);
// http://localhost:8080/download
app.get('/download', (req, res) => {
res.sendFile(path.resolve(__dirname, './file.csv'));
});
// http://localhost:8080/csv/file.csv
app.use('/csv', express.static(path.resolve(__dirname, './csv_files/')));
// Run HTTP server
httpServer.listen(port, () => console.log('Server is listening on *:' + port));
If you run this snippet, you can open http://localhost:8080/download and ./file.csv would be downloaded.
Following part of code is responsible for that:
app.get('/download', (req, res) => {
res.sendFile(path.resolve(__dirname, './file.csv'));
});
Or if you want to give access to the whole directory ./csv_files/ you can do this:
app.use('/csv', express.static(path.resolve(__dirname, './csv_files/')));
Just create ./csv_files/foo.csv file and go to http://localhost:8080/csv/foo.csv.
Does it make sense to you?
PS Working example:
// Libs
const express = require('express');
const http = require('http');
const path = require('path');
const fs = require('fs');
// Setup
const port = 8080;
const app = express();
const httpServer = http.createServer(app);
// http://localhost:8080/download
app.get('/download', (req, res) => {
const filename = path.resolve(__dirname, './file' + (new Date()).getTime() + '.csv');
fs.writeFileSync(filename, 'foo,bar,baz');
res.sendFile(filename);
});
httpServer.listen(port, () => console.log('Server is listening on *:' + port));
Whenever I'm hitting the endpoint, I keep getting empty file while locally generated file is correct and contains all the fields I need. I've tried piping directly to response but I would be getting:
Cannot pipe, not readable
Of course there might be something I'm doing wrong.
Similar question.
const PORT = 3000;
const express = require('express');
const fs = require('fs');
const csv = require('fast-csv');
const app = express();
app.listen(PORT, () => {
console.log(`Express server is listening on ${PORT}`);
});
app.get('/rates/csv', (req, res) => {
let ws = fs.createWriteStream(__dirname + '/tmp/rates.csv');
csv.write([
["a", "b"],
["a1", "b1"],
["a2", "b2"]
], {headers: true})
.pipe(ws);
console.log('FILE SAVED');
res.download(ws.path, 'rates.csv')
});
You can't pipe a writable stream to another writable stream.
https://medium.freecodecamp.org/node-js-streams-everything-you-need-to-know-c9141306be93