I defined a JSON, and post it to back end (Node.js).
var imj = {};
imj.images = [];
$.post("/image/uploadImages", imj, function(feedback){
.....
However, what the backend received was
{}
the "images" entry disappeared.
Here's the backend code:
exports.uploadImages = function(req, res) {
if (typeof req.body.images == 'undefined') {
return res.json({
code: 1,
message: "parameter incomplete"
})
}
.....
So the backend return the error {code:1, message:'parameter incomplete'}
Anyone knows why? If I want the backend to receive this empty array, what should I do?
What's the contentType nodeJS is expecting on the back-end? The default contentType for the $.post method is application/x-www-form-urlencoded. If you're endpoint is looking for application/json, you'll always see an empty input.
$.post sends url encoded data, so you need to use $.ajax and specify the content type as well as JSON stringify the data.
var data = {};
data.images = [];
$.ajax({
url: '/image/uploadImages',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(data)
}).done(function(data) {
console.log(data); // { images: [] }
});
On the server side make sure to use a body parser.
var app = require('express')();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.post('/', function (req, res, next) {
console.log(req.body); // { images: [] }
res.json(req.body);
});
app.listen(9000);
Related
I have below setup to call API with middleware to authorize it before success.
Calling API with token id with header object using jquery ajax,
$.ajax({
url : '/api/auth/fetchMycontent',
type: 'POST',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
cache: false,
context: this,
headers: {
"X-Access-Token": tokenId
},
data: JSON.stringify({
accountId: accountId
}),
success: function(data){
//render data in HTML
}
});
Setting node server as below,
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
// Add your middlewares:
var middleware = require("middlewares");
app.use(bodyParser.json());
app.all('/api/auth/*', middleware.apiValidate);
app.use('/', require('./modelApi'));
...
setting API in modelApi/index.js,
var express = require('express'),
router = express.Router(),
api = require('../api.js'),
router.post('/api/auth/fetchMycontent', api.fetchMycontent);
module.exports = router;
middleware.js file will be like
module.exports = {
apiValidate: function (req, res, next) {
var token = req.body.x_access_token;
if (token) {
elastic.fetchToken(table, token).then(function (data) {
if (data.hits.total > 0) {
**//authorization success but next() fails here <------**
next();
} else {
res.json({
message: "Invalid User access!!",
});
return;
}
});
}
},
};
From api.js,fetchMycontent function will be like
fetchMycontent : function(req, res) {
**console.log('not reaching after authorization success !!!')**
elastic.fectMycontent(table, req.body).then(function (data) {
res.set('Content-Type', 'application/json');
res.status(200);
res.send(data);
})
}
When i call api 'fetchMycontent', it calls middleware as expected and authorize it and does not call fetchMycontent()!!! What am i missing here? Please advise
Thanks in advance
I think you are missing to extend like
export class AuthenticationMiddleware implements ExpressMiddlewareInterface
and implement the use function
use(req, res, next)
Base url was added with two slash, Fixed by removing one / and it is working fine.
I am trying to implement a typeahead functionality as below.
html page
...
...
<input id="product" name="product" type="text" class="form-control" placeholder="Enter Product Name" autocomplete="off">
...
...
<script>
$(document).ready(function () {
fetchTypeAheadResult();
});
function fetchTypeAheadResult() {
$('#product').typeahead({
source: function (request, response) {
var formData = {
'product' : $('#product').val()
}
// var formData = $('form').serialize();
$.ajax({
url: "/search",
dataType: "json",
type: "POST",
data: formData,
contentType: "application/json; charset=utf-8",
success: function (result) {
var items = [];
response($.map(result, function (item) {
items.push(item.name);
}))
response(items);
// SET THE WIDTH AND HEIGHT OF UI AS "auto" ALONG WITH FONT.
// YOU CAN CUSTOMIZE ITS PROPERTIES.
$(".dropdown-menu").css("width", "100%");
$(".dropdown-menu").css("height", "auto");
$(".dropdown-menu").css("font", "12px Verdana");
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
}
});
},
hint: true, // SHOW HINT (DEFAULT IS "true").
highlight: true, // HIGHLIGHT (SET <strong> or <b> BOLD). DEFAULT IS "true".
minLength: 1 // MINIMUM 1 CHARACTER TO START WITH.
});
}
</script>
...
...
And my back end node js code is as following
'use strict';
const express = require('express');
const bodyParser = require('body-parser');
const request = require('request');
const app = express();
// configure the app to use bodyParser() to extract body from request.
app.use(bodyParser.urlencoded({ extended: true }));
// parse various different custom JSON types as JSON
app.use(bodyParser.json({ type: 'application/*+json' }));
app.post('/search', (req, res) => {
let searchText = req.body;
console.log('Search string >> ' + req);
console.log('Search string >> ' + JSON.stringify(req.body));
console.log('Search string >> ' + req.body.product);
// Not correct, but still trying if it works
// var result = triestrct.get(req.body.product);
res.send({test:'text'}); // TODO - to be updated with correct json
});
Now whenever I am trying to type on the "product" text field, it is invoking the back end /search api. However, I am unable to capture the value of product field.
Any help will be appreciated ? Note, I need typeahed functionality with ajax call to send input text value to back end.
Output of the three consol logs as following...
Search string >> [object Object]
Search string >> {}
Search string >> undefined
express doesn't parse the input provided to API by it self. Thus we need some additional tool like body-parser to fetch input from request and format it into JSON. This can be done without body-parser too.
Do go through this documentation it covers a lot.
Using body-parser, you need to setup body-parser with express:
```
const bodyParser = require('body-parser'),
// For Cross-Origin Resource Sharing
CORS = require('cors'),
express = require('express');
const app = express();
// Cross-Origin Resource Sharing
app.use(CORS());
// configure the app to use bodyParser() to extract body from request.
// parse urlencoded types to JSON
app.use(bodyParser.urlencoded({
extended: true
}));
// parse various different custom JSON types as JSON
app.use(bodyParser.json({ type: 'application/*+json' }));
// parse some custom thing into a Buffer
app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }));
// parse an HTML body into a string
app.use(bodyParser.text({ type: 'text/html' }));
// This will get you input at `req.body`
app.post('/search',(req,res)=>{
console.log(JSON.stringify(req.body));
});
```
Without using body-parser:
```
app.post('/', (req, res, next) => {
let body = [];
req.on('error', (err) => {
console.error(err);
}).on('data', (chunk) => {
// Without parsing data it's present in chunks.
body.push(chunk);
}).on('end', () => {
// Finally converting data into readable form
body = Buffer.concat(body).toString();
console.log(body);
// Setting input back into request, just same what body-parser do.
req.body = body;
next();
});
}, (req, res) => {
console.log(req.body);
});
```
req.body.product not req.query.product
IN POST verb use body-parser midlleware
const bodyParser = requier('body-parser');
const express = require('express');
const app = new express();
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
app.post('/search',(req,res)=>{
console.log(JSON.stringify(req.body));
});
I did not use typeahead before but this example is clear.
I have two node servers and I am trying to send files between them using a rest api. However when I am sending the data I get a "Unexpected token -"on the receiving server. On the sender I get an [Error: write after end].
My router code:
var express = require('express');
var multer = require('multer');
var path = require('path');
var Router = express.Router;
const MODULES_PACKAGES_UPLOAD_DIR = path.resolve('/tmp');
module.exports = function() {
var router = new Router();
var storage = multer.diskStorage({
destination: function(req, file, cb){
cb(null, MODULES_PACKAGES_UPLOAD_DIR);
}
});
var upload = multer({storage: storage});
router.post('/fileUpload', upload.array(), function(req, res){
debug('We have a a file');
//Send the ok response
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
res.end('\n');
}
The sending code:
var Util = require('util');
var http = require('request-promise');
var request = require('request');
var fs = require('fs');
var Post = require('http');
var FormData = require('form-data');
//Generate the form data
var formdata = modules.map(function(fileName){
return fs.createReadStream('/opt/files/'+fileName);
});
var data = getData(); //Gets the body of the code as a promise
return Promise.all(data)
.then(function(dataResults){
var options = {
method: 'POST',
uri: 'https://' + name +'/file',
rejectUnauthorized: false,
timeout: 2000,
body: {
keys: keyResults,
modules: modules,
},
formData: { <====== If I remove this section everything works
'module-package': formdata,
},
json: true // Automatically stringifies the body to JSON
};
request.post(options, function(err, response){
if( err){
debug('Error: ',err);
}
else{
debug('We posted');
}
});
The weird thing is that if I remove the formData section then everything works but when it is there I get an exception that says:
SyntaxError: Unexpected token -
at parse (/home/.../projects/node_modules/body-parser/lib/types/json.js:83:15)
Does anyone have any idea what I could be doing wrong??
Just in case anyone in the future comes with the same problem. As #Bergi mentioned. You cant have both json data and form data. You need to choose either one. The solution is to just pass the json data as apart of the form like.
var options = {
method: 'POST',
uri: 'https://' + name +'/file',
rejectUnauthorized: false,
timeout: 2000,
body: {
},
formData: {
'module-package': formdata,
keys: keyResults,
modules: modules,
},
json: true // Automatically stringifies the body to JSON
};
request.post(options, function(err, response){
if( err){
debug('Error: ',err);
}
else{
debug('We posted');
}
});
In my case, the header of the HTTP Request contained "Content-Type" as "application/json".
So here are the things to check:
Send only either form-data or json body. NOT BOTH.
Check for Headers if the "Content-Type" is mentioned. Remove that.
My client side
$.post("http://localhost:3000/scrape",
{
data: 'something'
},
function(data, status){
console.log(data);
});
What I do in node.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.post('/scrape', function (req, res) {
console.log(req.body.data)
});
But I got undefined in console.log(req.body.data), any idea why?
Your data must be of json format. since you are using bodyParser.json().
Try setting the http header, Content-type as application/json in your $.post call and send a valid json structure as data
$.ajax({
url: "scrape",
type: "POST",
data: JSON.stringify({ someData : "someData}),
contentType:"application/json; charset=utf-8",
dataType:"json",
success: function(data){
console.log(data)
},
error: function(){
console.log('error in sending request')
}
})
console.log(req.body.data)
returns undefined because the data is in req.body you should console.log(req.body)
and add app.use(bodyParser.urlencoded({extended: false})); so that data not in json format can also be parsed.
if you want req.body.data have data then make request like
$.post("http://localhost:3000/scrape",
{
data: {data: 'something'}
},
function(data, status){
console.log(data);
});
also your request is not sending any response you need to do something like
app.post('/scrape', function (req, res) {
console.log(req.body.data)
res.status(200).json({data: reqr.body.data});
});
hope it helps :)
I am building a simple application using Node.js. On the client, I am sending some JSON data using Ajax to the server with the following code:
var data = {};
data.title = "title";
data.message = "message";
$.ajax({
type: 'POST',
data: JSON.stringify(data),
contentType: 'application/json',
url: '/myresult',
processData: false,
success: function (data) {
console.log('success');
console.log(JSON.stringify(data));
}
});
The server side code handling this request is:
app.post('/myresult', function (req, res) {
var obj = {};
console.log('body: ' + JSON.stringify(req.body));
res.send(req.body);
});
However the console log prints the response bode as empty, i.e. body: {}.
Why is the body value empty and how can it be filled with the title and message?
Express gets a kind help from body-parser.
Use it as a middleware to get the actual body content:
app.use(require('body-parser').urlencoded({extended: true}));
and then leave your code as it was:
app.post('/myresult', function(req, res) {
var obj = {};
console.log('body: ' + JSON.stringify(req.body));
res.send(req.body);
});
I expect this will work for you, but please note bodyParser.json() as well, which might be better suited for your needs.
In addition, what's currently happening is since you have processData: false, it's basically sending this: ({"command":"on"}).toString() which is [object Object] and there's your body parser failing. Try removing processData flag entirely.