Get image sent from post in node.js - javascript

I need to use python to send an image through post and then download it on the node.js server side.
Python code:
import requests
from PIL import Image
import json
url = 'http://127.0.0.1:8080/ay'
files = {'file': open('image.jpg', 'rb')}
r = requests.post(url, data = files)
Node.js code:
var app = express();
app.use(bodyparser.json({ limit: '50mb' }));
app.use(bodyparser.urlencoded({ limit: '50mb', extended: true }));
app.post('/ay', function(req, res) {
var base64Data = req.body.file
require("fs").writeFile("out.png", base64Data, 'base64', function(err) {
console.log(err);
});
res.send('done');
});
But I can't seem to download the file properly on the server so I'm wondering what format python uses to open images and how I can fix the node.js code so that it can properly download the image.
Edit: there were a few issues with the code, I'm trying to use multer now but can't seem to get it working.
Python code:
import requests
url = 'http://127.0.0.1:8080/ay'
files = {'file': open('image.jpg', 'rb')}
r = requests.post(url, files = files)
Node.js code:
var express = require('express');
var multer = require('multer')
var upload = multer({ dest: 'uploads/' })
var app = express();
app.post('/ay', upload.single('avatar'), function (req, res, next) {
console.log(req.file)
res.send("done");
});
app.post('/ay', upload.array('photos', 12), function (req, res, next) {
console.log(req.files)
res.send("done");
});
I've tried both upload.single and upload.array but neither work.

So I finally figured it out using multer... incorrectly naming the key is why I couldn't use multer properly.
Python:
import requests
url = 'http://127.0.0.1:8080/ay'
files = {'file': open('image.jpg', 'rb')}
r = requests.post(url, files = files)
Node.js:
var express = require('express');
var multer = require('multer')
var upload = multer({ dest: 'uploads/' })
var app = express();
app.post('/ay', upload.array('file', 12), function (req, res, next) {
console.log(req.files)
res.send("done");
});

Have a look at this blog post which gives an example regarding how to access an uploaded file in node.js
In that example, after you load the bodyParser middleware, you have access to an object called req.files which contains the info regarding your uploaded file.
Do a console.log(req.files) and see what it displays.
The bodyParser middleware can be used to read uploaded files in Express v3, which is no longer maintained.
If you use v4 or above, you can use the connect-multiparty middleware, like this:
var multipart = require('connect-multiparty');
var multipartMiddleware = multipart();
app.post('/ay', multipartMiddleware, function(req, resp) {
console.log(req.body, req.files);
// don't forget to delete all req.files when done
});
Also, I think your Python code is not uploading properly. Try with:
requests.post('http://127.0.0.1:8080/ay', files={'image.jpg': open('image.jpg', 'rb')})

Related

Node Express 404 error when trying to load image uploaded by multer

Im trying to upload images with multer. Everything has worked before on localhost fine. Images get uploaded and i can view them from the url link the code provides. However once i have uploaded it on a server im starting to get this error : "Cannot GET /marketplace-api/rest-api/image/1650484814178.jpg".
I have not provided link to server/domains to the question in case people say thats the problem.
Here is my code:
const express = require('express');
const app = express();
const multer = require("multer");
const path = require("path");
const db = require('./db');
const cors = require('cors');
const port = 5000;
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true , limit: '50mb'}));
app.use(cors());
app.use("/image", express.static("image"));
let imageName = "";
const storage = multer.diskStorage({
destination: path.join("./image"),
filename: function (req, file, cb) {
imageName = Date.now() + path.extname(file.originalname);
cb(null, imageName);
},
});
const upload = multer({
storage: storage,
limits: { fileSize: 3000000 },
}).single("myImage");
app.post("/marketplace-api/rest-api/upload-image", (req, res) => {
upload(req, res, (err) => {
if (err) {
console.log(err);
} else {
return res.status(201)
.json({ url: "http://link to domains/marketplace-api/rest-api/image/" + imageName });
}
});
});
app.listen(port, () => {
console.log("server run in port", port);
});
ok, few things, 1. you dont have any get functions, which means you cant post to this location, i suggest doing this:
app.get('/', (req, res) => {
res.sendFile(__dirname + "/index.html");
});
and create a file called index.html, go on your site (localhost), and it should work, after that add a form in the html file, it should look something like this
<form action = "/marketplace-api/rest-api/upload-image" method = "POST">
<input type = "file" name="image">
<input type = "submit">
</form>
this will add a basic form where you can upload your photo.
there are a few more stuff to add / change, i will fix everything and make it a repo then send it here

Postman Post request to NodeJS server does not give me the files properties

Good morning. I'm developing a portfolio app with projects. I did a mongoDB database and a NodeJS and express conexion to this database. I'm doing a controller with a method that allows me to upload a image to the database. I did this method, but when I use it with PostMan, the image is uploaded to the folder I indicate, but the files arguments don't appear and I need then to upload to the database.
I upload the code
Controller
uploadImage: function(req, res){
var projectId = req.params.id;
var fileName = "Imagen no subida...";
if(req.files){
return res.status(200).send({
files: req.files
});
}else{
return res.status(200).send({
message: fileName
});
}
}
Routes
'use strict'
var express = require('express');
var ProjectController = require('../controllers/project');
var router = express.Router();
var multipart = require('connect-multiparty');
var multipartMiddleware = multipart({ uploadDir: './uploads' });
router.get('/home', ProjectController.home);
router.post('/test', ProjectController.test);
router.post('/save-project', ProjectController.saveProject);
router.get('/project/:id', ProjectController.getProject);
router.get('/projects', ProjectController.getProjects);
router.put('/project/:id', ProjectController.updateProject);
router.delete('/project/:id', ProjectController.deleteProject);
router.post('/upload-image/:id', multipartMiddleware ,ProjectController.uploadImage);
module.exports = router;
app.js
'use strict'
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
// cargar archivo Rutas
var routes = require('./routes/project');
// Middlewares
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
// CORS
// Rutas
app.use('/api', routes);
// exportar
module.exports = app;
PostMan
I use form-data and I add an image.
Response:
{
"files": {}
}
I think in files JSON there are differents params to upload image to the dataBase, like filePath, fileName...
Thanks in advance
I think it should be req.files.file not req.files
If req.files.file does not exist, try to console.log(req), and console.log(req.files) to trace the file
Update
check that the Content-Type in the headers sections in postman is "multipart/form-data"
then you can find your file in req.files.image, as you name it image in form-data body section
hope it helps
thank you for your answer.
I did the two things, but when I do the console.log(req.files) the response is {}, and when I do console.log(req.files.file) the response is undefined.
I don't know what happens, I'm using a .jpg extension image.
Again thank you
thank you.
I send you an image of the PostMan request. I send you in i.stack because is the only way I can send the image.
[![[1]: https://i.stack.imgur.com/NHDog.png][1]][1]
The code:
// Multer
const storage = multer.diskStorage({
destination: function(req, res, cb){
cb(null, './uploads')
},
filename: function(req, file, cb){
cb(null, file.fieldname + "-" + Date.now())
}
})
const upload = multer({ storage: storage });
The function:
uploadImage: function(req, res, next){
console.log(req.file);
}
The request:
router.post('/upload-image/:id', upload.single('image'), ProjectController.uploadImage);

File upload with multer returning undefined

I'm currently trying to implement file-uploads for my application, in which I use ReactJS, node.js with express, and MongoDB and mongoose. I'm using multer middleware for fileuploads, however, despite looking at all similar questions here on SO and also looking it up, I can't seem to get it to work.
This is my React form:
addUser (event) {
var formfile = new FormData();
formfile.append("file", this.state.filesToBeSent);
axios.post('adduser',
JSON.stringify({
entry: this.state.currname,
passwrd: this.state.currpasswrd,
formfile : formfile
}), {
headers: {"Content-Type": "application/json"}
}
)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
render() {
return (
<form onSubmit={this.addUser} encType="multipart/form-data" >
<input value={this.state.currname} />
<input value={this.state.currpasswrd} />
<input type="file" value={this.state.filesToBeSent} name="file" />
<button type="submit" >Add</button>
</form>
);
}
This is my node.js file:
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var User = require('../models/User.js');
var bodyParser = require('body-parser');
var multer = require("multer");
const uuidv4 = require("uuid/v4");
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cd(null, "./uploads");
},
filename: (req, file, cb) => {
const newFilename = `${uuidv4()}${path.extname(file.originalname)}`;
cb(null, newFilename);
},
})
const upload = multer({ storage });
router.post("/", upload.single("file"), (req, res) => {
console.log(req.file + " and exit.");
});
module.exports = router;
I'm not doing anything with the text-inputs just yet, because I wanted to get the file upload to work first.
I tried out a variety of things, like using async(req, res) in router.post(). I tried using x-www-form-urlencoded as content-type and to only send the file without text-inputs( I specified formfile as data to be sent without the whole JSON.stringify(), however, I didn't manage to get it to work.
Can anyone spot a mistake in my code? Or does anyone have any other ideas about how to get it to work?
Edit:
Setting up the adduser-route in app.js:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var adduser = require('./routes/adduser');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/adduser', adduser);
Did you test your post endpoint? You can use a rest client such as Postman or Insomnia just to make sure that this is not the problem. Send a POST request to the endpoint and see if it gets invoked.
Then I guess you should use "/adduser" on your client and not "adduser" if you endpoint is exposed at "localhost:port/adduser". Your code doesn't show how you set up the route in the node.js code.
Finally you may want to use an higher level component to perform the upload, which can handle multipart for you in case you upload larger files. I found the combination react-dropzone + Multer being quite convenient.
try this :
router.post("/", upload.single("formfile"), (req, res) => {
console.log(req.formfile + " and exit.");
});
i think the headers should be:
{"Content-Type": "multipart/form-data"}
instead of application/json.

Cloudinary File Upload Error

I'm writing a REST API on using Express.js. The API needs to accept a video file from the client and upload it to cloudinary. When I use the api to return the file back to the client (as a test) everything works perfectly. When I then try to upload the same file to cloudinary I get an error. the error says:
"file.match is not a function"
I'm not sure what file.match even is or why it is giving me a problem. If anyone else has had this issue how did you solve it?
Below is the code that is giving me issues:
app.js
var express = require('express');
var formidable = require('express-formidable');
var app = express();
app.use(formidable());
var routes = require('./routes');
app.use('/routes', routes);
var port = process.env.PORT || 3000;
app.listen(port, function() {
console.log('Express server is listening on port ' + port);
});
routes.js
var express = require('express');
var cloudinary = require('../cloudinary.js').cloudinary;
var router = express.Router();
router.post('/upload', function(req, res, next) {
cloudinary.uploader.upload(req.files, function(result) {
console.log(result);
});
});
module.exports = router;
cloudinary.js
var cloudinary = require('cloudinary');
cloudinary.config({
cloud_name: 'name',
api_key: 'key',
api_secret: 'secret'
});
module.exports.cloudinary = cloudinary;
I was able to solve the issue. It was not a problem on Cloudinary's end. The key was to only send the location of the file.
WORKING routes.js
var express = require('express');
var cloudinary = require('../cloudinary.js').cloudinary;
var router = express.Router();
router.post('/upload', function(req, res, next) {
var fileGettingUploaded = req.files.fileToUpload.path;
cloudinary.uploader.upload(fileGettingUploaded, function(result) {
console.log(result);
});
});
module.exports = router;
Did you try to specify the resource_type as video -
cloudinary.uploader.upload(req.files,
function(result) {console.log(result); },
{ resource_type: "video" });
If you're uploading images and videos you can use the auto as resource_type.

How to upload image in Node.js

I am complete Newbie to Node.js.I just want to learn upload and showing images using ajax like i do in php.I found most of the tutorials tough for me.To get started I have tried using this code
var express = require("express");
var app = express()
var bodyParser = require('body-parser')
//all environment
app.use(bodyParser())
var form = "<!DOCTYPE HTML><html><body>" +
"<form method='post' action='/upload' enctype='multipart/form-data'>" +
"<input type='file' name='image'/>" +
"<input type='submit' /></form>" +
"</body></html>";
app.get('/', function (req, res){
res.writeHead(200, {'Content-Type': 'text/html' });
res.end(form);
});
/// Post files
app.post('/upload', function(req, res) {
console.log('Hello world');
console.log(req.files);
});
app.listen(8080)
But am getting UNDEFINED for req.files.can anybody tell why?.Please forgive me if its a stupid question.And also help with some resources.Thank you in Advance.
req.files is for express v3, you are using v4.
Now body-parser only handles urlencoded and json bodies.
For multipart bodies you should use an alternative.
https://github.com/expressjs/body-parser
For example with multer:
var express = require('express')
var multer = require('multer')
var app = express()
app.use(multer({ dest: './uploads/'}))
/// Post files
app.post('/upload', function(req, res) {
console.log('Hello world');
console.log(req.files);
});
app.listen(8080)
With express 4, busboy is an excellent way to handle uploaded images. Let's look at a cut-down example from Miaou:
exports.appPostUpload = function(req, res){
var busboy = new Busboy({ headers: req.headers }), files=[];
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
var chunks = [];
file.on('data', function(chunk) {
chunks.push(chunk);
// todo : abort if sum of chunk.lengths is too big (and tell the client he's fat)
});
file.on('end', function() {
files.push({name:fieldname, bytes:Buffer.concat(chunks)});
});
}).on('finish', function() {
if (!files.length) {
return res.send({error:'found nothing in form'});
}
// we can now work with the items in `files` like you normally would.
});
req.pipe(busboy);
}

Categories