im trying to create a simple webpage with some server side functions but somehow 2 things arent working as they supposed to work.
via html button im running a clientside javascript that does a http post request.
Client side javascript
httpRequest = new XMLHttpRequest()
httpRequest.open('POST', '/test2')
httpRequest.send(var1,var2,var3,var4);
Server.js
var express = require('express');
var bodyParser = require("body-parser");
var dbFunc = require("./dbFunctions.js");
var app = express();
var path = require('path');
var port = 8888;
//allow to use body-parser
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
//allow to use static files
app.use(express.static("public"));
//listen to smth
app.post('/test2', function (req, res) {
console.log("worked");
});
//start server
app.listen(port);
console.log("Server running on port" + port);
My server detects this post http request and does the "console.log" but how do i get the parameters from the http.request as a variable? I tried to work with bodyParser but somehow my object is always empty.
Another thing is, ive created another Javascript file(dbFunctions.js) and also implemented it in the server file but if i try to run a function(dbFunc.test("hello") for example) it says "dbFunc.test is not a function".
dbFunctions.js
function DBFunctions(){
function test(a){
console.log(a);
}
}
Ive also tried to do something like this, but this gave me the same error.
function test(a){
console.log(a);
}
Could someone give me a hint or tell me what i am missing?
Answer1:
The way you are sending data into post request is wrong, you slould send in format of,
xhttp.send("val1=val1&val2=val2");
httpRequest = new XMLHttpRequest()
httpRequest.open('POST', '/test2')
httpRequest.send(var1=var1&var2=var2&var3=var2&var3=var3);
To POST data like an HTML form, add an HTTP header with setRequestHeader(). Specify the data you want to send in the send() method:
httpRequest = new XMLHttpRequest()
httpRequest.open('POST', '/test2')
httpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
httpRequest.send(var1=var1&var2=var2&var3=var2&var3=var3);
In your server.js, use req.body to get those values.
app.post('/test2', function (req, res) {
console.log("worked");
console.log(req.body)
});
XMLHttp request example
Answer2:
From your dbFunctions.js file you should export your function using module exports in node js.
dbFunctions.js:
var exports = module.exports = {};
exports.test = function(a) {
console.log(a);
};
You can also do as,
module.exports = {
test: function(a) {
console.log(a)
},
}
Now in your server.js
var dbFunc = require("./dbFunctions.js");
dbFunc.test();
Node js module exports
All your posted variables will be available in req.body try console.log(req.body).
Secondly you most probably not exporting test function from dbFunction.js, that's why getting "dbFunc.test is not a function" because dbFunc.test is undefined.
Note: As mentioned in one of the comment, you need to use httpRequest.send(var1,var2,var3,var4); in the right way. It does not expect multiple parameters.
Like: httpRequest.send("var=var1&var1=var2")
Please refer: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send
Related
I'm trying to create a small service that converts images from one type to another.
I'll get to the conversion part later, right now i cant even send it to the node server properly.
i have a simple script that's supposed to use filesystem to read an image and then POST it to a node server endpoint.
I couldn't find a way to do this anywhere online
i tried all kinds of different ways and formats, but on the endpoint the req.body is always an empty object or just an error
const fse = require('fs-extra');
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
var xhr = new XMLHttpRequest();
fse.readFile('testimg.png', function (err, data) {
if (err) {
throw err
}
console.log(data)
xhr.open("POST", 'http://localhost:3000/convert', true); // true for asynchronous
xhr.setRequestHeader('Content-Type', 'application/upload');
xhr.send(data)
})
and this is the server endpoint:
var express = require('express');
var router = express.Router();
router.get('/', (req,res)=>{
res.send("hello")
})
router.post('/', async(req,res)=>{
console.log(req.body);
res.send("Hello i work")
})
module.exports = router;
What i want is to get the data on the server endpoint and to be able to process it and convert it for example: upload jpg and convert and send back as png or the opposite.
Help highly appreciated
I have a bit of an issue when i try to create an object prototype in my node/express app.
I first start by creating the prototype like so:
Object.prototype.printObject = function () {
return console.log(this);
}
Now the issue is when I call this function. For instance when i call the function like this:
let request = {1:2}
request.printObject();
*//Logs {1:2}*
No error occurs. Yet when I call the function like this:
let request = req.body
request.printObject();
My program crashes with error: TypeError: request.printObject is not a function
Does anyone have any clue as to why this occurs?
if you require('body-parser')? or req.body is undefined,you should do this first
var bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({ extended: false }))
You have added the 'printObject' method on the prototype of Object. So if req.body is an Object, you should be able to call the method.
Try checking the type of req.body using console.log(typeof req.body) to verify that it is an Object.
If it is not, you should use the node module 'body-parser' to populate req.body with the parsed body content.
For example, parts of your server code might look like this:
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json()); // Data is being sent to the server in JSON format
app.post('/my/endpoint', function(req, res){
req.body.printObject();
});
The 'body-parser' module supports other formats as well. I used JSON as an example. You can find everything they support here: https://www.npmjs.com/package/body-parser
Insteat of trying to prototype any Object, you could create a middleware function like so:
app.use(function (req, res, next) {
console.log('req');
//you could also add any function to req,even so thats not a common thing to do
req.printObject = function { ... }
next();
});
Probably the problem with your approach is, that you add the function to the Object prototype after the request object was created.(EDIT: This is wrong, see comments)
I want to send a jsonstring to my server from client. I'm pretty sure I'm sending it OK, But i can't seem to figure out how to read it on server-side. The variable 'sendJSONString' is what I'm trying to send. I've seen many examples where the data is sent in the URL and then extracted. But I'd really rather not do that.
On Client Side i have this code:
module.exports = function sendAuthToServer(retVal, _userName, _AUTHKey){
var sendJSONString = JSON.stringify({userName:_userName, AUTHKey:_AUTHKey});
var gotData = [];
var xhr = new XMLHttpRequest();
xhr.open('GET', encodeURI('/AUTH'));
xhr.onload = function() {
if (xhr.status === 200) {
gotData = JSON.parse(xhr.responseText);
retVal(gotData);
}
else {
alert('Request failed. Returned status of ' + xhr.status);
}
};
xhr.send(sendJSONString);
}
On Server Side i have this.
module.exports = function giveQueryList(app){
app.get('/AUTH', function(req, res) {
res.json('ServerResponse');
console.log(req.ip, req);
});
}
app is using express and is set up like this
//CONFIG ROUTER/SERVER
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));//MAKE CONTENT IN VIEWS FOLDER AVAILABLE TO CLIENT
app.set('port', process.env.PORT || 8888);
//USE MIDDLEWARE
app.use(express.static(path.join(__dirname, 'views')));
You are sending the data with a GET HTTP verb. Try changing that to POST or PUT (you'll need to adjust your express route accordingly).
If not done already, you should use middleware like body-parser to parse the information send by the client. Then, you can access the information posted/puted by the client on the req.body object.
So the client makes a get request using a button on the index page. This sends some information to a route which has been set up as follows:
app.js
var route = require('./routes/index');
var button = require('./routes/button');
app.use('/', index);
app.use('/button', button);
The request is sent from a client-side directory to the node framework whenever someone presses the button. If the request is sent to 'localhost:port/button', then the button.js file mentioned above will receive the request. So in the button.js file we have something like the following:
var express = require('express');
var router = express.Router();
var someData = '';
router.get('/', function (req, res, next) {
//make a get request here such that someData
//receives whatever the request returns from another
//set up framework(i.e. Spring...)
someData = getRequest('some other URL');
res.send(someData);
};
module.exports = router;
The problem here is that the getRequest('some other URL') within the router get request never receives any information.
Also (as a side-note), I cannot seem to find in the express API as to why we have
router.get('/')...
instead of
router.get('/button')...
to access and make requests to the button page.
Any help would be very much appreciated!
You want to make a request to some other REST API running somewhere else right?
You can use node-rest-client for that.
I guess you are confusing what is server code and client code or do I´m missing something?
I´ll try to explain the way it works:
Server code:
var express = require('express');
var router = express.Router();
var someData = '';
router.get('/yearStations/:id', function (req, res, next) {
//make a get request here such that someData
//receives whatever -the id parameter- the request returns from another
//This is express.js
someData = getYourDataFromDataBase(req.params.id);
res.send(someData);
};
module.exports = router;
Client code:
JS (angular.js)
$scope.getInfo = function() { //here you make the GET call to the server
$http.get("http://localhost:XXXX/yearStations/Spring").then(
function(success){
alert(success.data);//this should be your data
});
};
HTML
<button ng-click="getInfo()">getInfo</button>
I am building a webservice, for which i am using nodejs, phantomjs and expressjs. I am learning all the three.
I want to serve a delayed response to the clients after processing their query. Like for example,
I am processing certain inputs from my client, then, i want to process the data at the backend which will take approx 10 sec on an avg. Then i wanted to serve this page to the client.
Is it possible in node to send multiple responses to the same request or delayed responses so that the template will automatically update the contents.
Or , should i use the same method , like store the json in a file in the server , then serve the page with ajax which will query the page.
please help me. here is the code which i wrote ,
app-server.js(the main file):
// import express module
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
// define all required template files to be served and also define the template engine
app.engine('.html', require('ejs').__express);
app.set('views', __dirname + '/views');
app.set('view engine', 'html');
// Useful modules
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
// import the routes
require('./router')(app);
app.listen(8080);
router.js:
var crypto = require('crypto');
var express = require('express');
module.exports = function (app) {
// define the static routes.
app.use('/static', express.static('./static'));
app.use('/media', express.static('./media'));
//defining the controller.
var parserlib = require('./controller.js')
// Define the home root path
app.get('/', function (req, res) {
// shows the home search page.
res.render('index', {content:'template success'});
});
app.get('/search', function(req, res){
res.redirect('/');
});
app.post('/search', parserlib.parserlib);
}
controller.js:
var crypto = require('crypto');
var path = require('path')
var childProcess = require('child_process')
exports.parserlib= function(req, res){
var output = '';
var url = req.body.search_url;
var childArgs = [
path.join(__dirname, 'external-script.js'),
url,
]
// execute the script in a separate thread.
childProcess.execFile(binPath, childArgs, function(err, stdout, stderr) {
// handle results
console.log(stdout);
output = stdout;
//console.log(err);
//res.send(output);
});
//res.send(output);
};
so , what i want to see is, first send a response to client stating that its loading, then i want to update the with processed data. In other languages its not possible to send multiple responses. Not sure about nodejs.
Also, do i have to store the json output from the processed lib to a file and then use ajax to query ? or is it possible to directly update the json object to the client ?
Thanks
This is just not how HTTP works. The clients won't expect it. This has nothing to do with Node or any other framework. The way to do what you're attempting is to actually send a response that the thing is loading, and then have some other mechanism for reporting state.
As an example, you might design a RESTful API. In that RESTful API you might define a endpoint for creating new things:
POST /api/things
The client would post data to that to create a new thing. The response should be something that provides a location of the newly created resource, for example an HTTP 301 to /api/things/1.
If the user goes to /api/things/1 and the thing isn't done getting made yet, then you can either do a temporary redirect (303) to /api/things/1/status which provides some helpful status information, or just issue a 404.
If you actually want to send back server-side pushes of status information, then you should be looking at WebSockets or a pure Socket API of some kind, neither of which is provided by Express, but both of which are available in Node (checkout the socket.io library and the net core library)