I am using node js with express framework and rest api
for rest api client i am using postman extension with chrome browser
here i am able to get values from option "x-www-form-urlencoded" but i am not able to get values from "form data" i want to get values from "form data" option and also need to upload image file.
please help me any to achieve this. i want to get values from "form data" option and also image. please help me.
Below i have mentioned code what i have used.
var express = require('express');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var http = require('http').Server(app);
var mysql = require('mysql');
var util = require('util');
var trim = require('trim');
var validator = require('validator');
var bodyParser = require('body-parser');
var Ingest = require('ingest');
var multer = require('multer');
var upload = multer({ dest: 'uploads/' });
var type = upload.single('recfile');
passport = require('passport')
, LocalStrategy = require('passport-local').Strategy;
async = require('async');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.post('/upload', function(req, res){
console.log(req.file); // "form-data" values not able to get here
console.log(req);// "form-data" values not able to get here
console.log('body : '+JSON.stringify(req.body));// "form-data" values not able to get here
});
i didn't set any content type in postman header
app.post('/upload', function(req, res){
console.log('req.headers \n '+JSON.stringify(req.headers));
console.log('req.body.file :- '+req.body.file);
console.log('\n\n req.body :- '+JSON.stringify(req.body));
});
I got the below result for the above code.
req.headers
{"host":"localhost:3001","connection":"keep-alive","content length":"5808","cache-control":"no-cache","origin":"chrome-extension://mkhojklkhkdaghjjfdnphfphiaiohkef","password":"password","user-agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36","username":"User2","content-type":"multipart/form-data; boundary=----WebKitFormBoundaryV4zAIbjEyKYxLRWe","accept":"*/*","accept-encoding":"gzip, deflate","accept-language":"en-US,en;q=0.8","cookie":"connect.sid=s%3Atz4f1ZgJkaAjuDD1sOkMB9rr.Z8EUIyxEcr0EyFQL96v0ExGRidM3SAVTx8IIr52O0OI"}
req.body.file :- undefined
req.body :- {}
Yes the same problem facing me several times and according my experience you do't set the content-type in postman header because it should be undefined and node server automatically set the content type according to requirement. If you set the content-type then you do't get any image and other data in the node server .
You get the image from the req.body.file
you get the other data from req.body
app.use(multipart()) in middleware
Procedure how to use multipart as middleware
var multipart = require('connect-multiparty');
global.app = module.exports = express();
app.use(multipart());
I got solution with help of the below code
var express = require('express');
var router = express.Router();
var util = require("util");
var fs = require("fs");
var formidable = require('formidable');
var path = require('path');
router.post("/upload", function(req, res, next){
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
// `file` is the name of the <input> field of type `file`
console.log(files);
console.log(fields);
res.writeHead(200, {'content-type': 'text/plain'});
res.write('received upload:\n\n');
res.end(util.inspect({fields: fields, files: files}));
});
form.on('error', function(err) {
console.error(err);
});
form.on('progress', function(bytesReceived, bytesExpected) {
var percent_complete = (bytesReceived / bytesExpected) * 100;
console.log(percent_complete.toFixed(2));
});
form.on('end', function(fields, files) {
/* Temporary location of our uploaded file */
var temp_path = this.openedFiles[0].path;
/* The file name of the uploaded file */
var file_name = this.openedFiles[0].name;
/* Location where we want to copy the uploaded file */
var new_location = 'public/images/';
fs.readFile(temp_path, function(err, data) {
fs.writeFile(new_location + file_name, data, function(err) {
fs.unlink(temp_path, function(err) {
if (err) {
console.error(err);
} else {
console.log("success!");
}
});
});
});
});
});
I think you need to use body-parser for this and also need to update your app.js as
app.use( bodyParser.json() ); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
I was facing same problem I was not able to get form data fields body parser is not enough to get those values. Hitting google searched a lot of stuff about it but nothing works. Here is the solution how I got form data values.
Note: I am using typescript instead of js
Install multer package: npm i multer
Now in app.ts or app.js import accordingly:
import multer from "multer"
Define the multer function
const upload = multer(); // config
After body parser:
app.use(upload.any());
Related
I'm trying to retrieve data from Keepa using express js and HTTP module,
Keepa sending all data as gzip.
I was challenged to get the data properly and I got a previous error-Unexpected token in JSON at position 0,
So I have installed 'decompress-response' module which resolved this issue but now I'm getting half of the JSON data and then a new syntax error appears - unexpected end of json input Node Js
I'm trying to figure what am I missing here.. hope you can help me.
const express = require("express");
const https = require("https");
const decompressResponse = require("decompress-response");
const bodyParser = require("body-parser");
const app = express();
app.use(bodyParser.urlencoded({extended: true}));
app.get("/", function(req, res){
res.sendFile(__dirname + "/index.html");
});
app.post("/", function(req, res){
console.log(req.body.asinId);
const query = req.body.asinId;
const apiKey = "MY_API_KEY";
const url = "https://api.keepa.com/product?key="+ apiKey +"&domain=1&asin="+ query;
https.get(url, function(response){
response = decompressResponse(response);
console.log(response.statusCode);
console.log(response.headers);
var data;
response.on("data", function(chunk) {
if (!data) {
data = chunk;
} else {
data += chunk;
}
const asinData = JSON.parse(data);
console.log(asinData);
res.send();
});
});
});
Please try to print the response before "response = decompressResponse(response);". And let me know what you get there.
I am sending the following request to my server using postman:
I try to access the image in my application using the following code:
app.js
var express = require('express');
var bodyParser = require('body-parser');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
app.use(bodyParser.raw({
type: 'image/png',
limit: '10mb'
}));
app.use('/', indexRouter);
app.use('/users', usersRouter);
module.exports = app;
index.js (router)
var express = require('express');
const router = express.Router();
var Jimp = require('jimp');
/* GET home page. */
router.get('/', function(req, res) {
res.render('index', { title: 'Express' });
});
router.post('/a', function(req, res) {
var image = req.body;
try{
Jimp.read(image, (err, input) => {
if (err) throw err;
input.sepia();
input.getBuffer(Jimp.AUTO, (err, output) => {
if(err) throw err;
res.writeHead(200, {'Content-Type': 'image/png' });
return res.end(output, 'binary');
});
});
}catch (err){
return res.status(400).send(`Error: ${err.message}`).end();
}
});
module.exports = router;
I was first using a form (with the help of express-fileupload library) to send the image and this worked fine, so I know the problem has to be somewhere before the line var image = req.body.
For the Jimp functions (image processing library) to work, the image has to be a buffer representing the png image.
When running console.log(image), the console outputs {}.
Can anybody show me a way to read the png as a buffer when it is sent as a Binary file?
Nevermind, I just had to change the Content-Type header in my request to image/png -.-
can you rewrite function with lib multer?
const multer = require('multer')
const storage = multer.memoryStorage()
const upload = multer({ storage: storage })
router.post('/a', upload.single('image'), function(req, res, next) {
const image = req.file.buffer
});
or with formidable?
var formidable = require('formidable' );
router.post('/a', (req, res) => {
const form = new formidable.IncomingForm();
form.parse(req, (error, fields, files) => {
const image = files.image;
})
});
new to NodeJS and I am trying to get a basic endpoint going. I actually have three different controllers, but one of them will not work. Here is my app.js
var express = require('express');
var app = express();
var db = require('./db');
var config = require('./config/config'); // get config file
global.__root = __dirname + '/';
var ApiController = require(__root + 'auth/ApiController');
app.use('/api/auth', ApiController);
var UserController = require(__root + 'user/UserController');
app.use('/api/users', UserController);
var AuthController = require(__root + 'auth/AuthController');
app.use('/api/auth/users', AuthController);
module.exports = app;
The UserController and AuthController work great but the ApiController:
//this controller handles api token
var express = require('express');
var router = express.Router();
var bodyParser = require('body-parser');
router.use(bodyParser.urlencoded({ extended: false }));
router.use(bodyParser.json());
router.get('/apiToken') , function(req, res) {
console.log("received request at /apiToken");
res.status(200).send({ token: config.api.token });
};
module.exports = router;
When I try this in Postman you can see:
I know it has to be something really simple because the failing call is nearly identical to the working ones - but I just don't see it.
You have a coding mistake here with a closing paren in the wrong place on this line that happens to not make an interpreter error, but does not execute as intended:
router.get('/apiToken') , function(req, res) {
// here ^
So change this:
router.get('/apiToken') , function(req, res) {
console.log("received request at /apiToken");
res.status(200).send({ token: config.api.token });
};
to this:
router.get('/apiToken', function(req, res) {
console.log("received request at /apiToken");
res.send({ token: config.api.token });
});
FYI, there is no need to do res.status(200) as that is the default status already. You can just use res.send(...) and the status will be set to 200 automatically. You only need to use res.status(xxx) when you want the status to be something other than 200.
Also, running your code though something like jshint will often complain about these types of mistakes that (somewhat by accident) don't throw an interpreter error.
I am trying to post data to a mongo DB through a URL of a browser. I was able to get it working using only expressJS, but I am having difficulty getting it working with mongodb. I'm still very new to this, so I am hoping that I am just missing a simple component and that I am at least on the right track.
When I enter "http://localhost:27017/api/users?id=4&token=sdfa3" or "http://localhost:27017/nodetest5/api/users?id=4&token=sdfa3" into the url, I'd like to see "4 sdfa3" on the webpage. Right now I am just getting a webpage with the message: "It looks like you are trying to access MongoDB over HTTP on the native driver port."
Here is my server.js file:
// packages
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var app = express();
var bodyParser = require('body-parser');
//db stuff
var mongo = require('mongodb');
var monk = require('monk');
var db = monk('localhost:27017/nodetest5');
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded
//make accessible mongo db accessible to router
app.use(function(req, res, next){
req.db = db;
next();
})
// routes
app.get('/api/users', function(req, res) {
//get values from URL
var id = req.param('id');
var token = req.param('token');
res.send(user_id + ' ' + token + ' ');
});
// POST to localhost
// parameters sent with
app.post('/api/users', function(req, res) {
//internal DB value
var db = req.db;
//values from URL
var user_id = req.body.id;
var token = req.body.token;
//set collection
var collection = db.get('usercollection');
//Submit to DB
collection.insert({
"id" : id,
"token" : token
}, function (err, doc){
if (err) {
res.send("Error encountered when trying to add entry to database.");
}
else {
res.send(user_id + ' ' + token + ' ');
}
});
});
Thank you!
The HTTP interface for MongoDB can be accessed via port number 28017. You'll need to provide the --rest option to mongod:
`$ mongod --rest`
You can read more in the HTTP Interface documentation.
You should exercise caution when using the HTTP interface. From the MongoDB documentation:
WARNING
Ensure that the HTTP status interface, the REST API, and the JSON API are all disabled in production environments to prevent potential data exposure and vulnerability to attackers.
I'm trying to create a simple web service in nodejs that accepts a file and saves it.
Here is my code.
var express = require('express');
var app = express();
var fs = require('fs');
var sys = require('sys');
app.listen(8080);
app.post('/upload', function(req, res) {
console.log(req.files);
var fileKey = Object.keys(req.files)[0];
var file = req.files[fileKey];
fs.readFile(file.path, function(err, data) {
fs.writeFile(__dirname, data, function(err) {
res.redirect("back");
});
});
});
I'm using fiddler to upload the file.
console.log(req.files);
gives undefined. An exception is also thrown:
Object.keys called on non-object
Any idea what I may be doing wrong?
You don't seem to be using the bodyParser middleware which is required to parse uploads (amongst other things):
app.use(express.bodyParser());
app.post('/upload', function(req, res) { ... });