The problem I'm having is, the content that I try to send in my post request to the server doesn't get sent, but the request works.
Here's the code for the client:
$("#searchBtn").click(function(e){
try{
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "/search/searchRequest", true);
console.log(($("#searchedSymptoms").val())) // gets posted in the console correctly
xhttp.setRequestHeader("Content-type", "text/plain"); // doesn't work without it either
xhttp.send($("#searchedSymptoms").val());
//xhttp.send(JSON.stringify($("#searchedSymptoms").val())); // doesn't work either
xhttp.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
console.log(xhttp.responseText); // gets the correct response from server
}
else{
console.log(xhttp.responseText);
}
};
}
catch(err){
console.log(err);
}
});
And here's the server-side code:
var express = require("express");
var router = express.Router();
router.post("/searchRequest", function(req, res, next){
console.log("must get the client request:");
console.log(req.body);
//console.log(JSON.stringify(req.body)); // doesn't work either
});
In the server, what get's outputed to the console is this:
{}
Any thoughts on what I'm doing wrong ?
You need to use a text body-parser, Express won't do it by default, here's an example, using pretty much the same server side code you are:
"use strict";
var express = require("express");
var router = express.Router();
var bodyParser = require("body-parser");
router.post("/searchRequest", function(req, res, next){
console.log("must get the client request:");
console.log("SearchRequest: " + req.body);
res.end('ok', 200);
});
var port = 8081;
var app = express();
app.use(bodyParser.text());
app.use(router);
app.listen(port);
console.log("Express listening on port " + port);
You can configure the way the text body parser operates exactly by using the guide here:
https://www.npmjs.com/package/body-parser#bodyparsertextoptions
Related
I have the following node express function:
var express = require('express');
var app = express();
// Listen on port 8000, IP defaults to 127.0.0.1
var server = app.listen(8000, function() {
console.log("node express app started at http://localhost:8000");
});
app.get("/test",
function(error, request, response, next) {
request.set("Content-Type", "text/html; charset=UTF-8");
if (error) {
request.status(403);
return next();
}
var id = request.query.snuid;
var currency = request.query.currency;
var mac_address = request.query.mac_address;
var display_multiplier = request.query.display_multiplier;
//
request.status(200);
});
When I load up the browser and enter in the url:
http://localhost:8000/test?snuid=1234¤cy=1000&mac_address=00-16-41-34-2C-A6&display_multiplier=1.0
Im not sure why I am getting this error!? Not sure, it should work based on the documentation and examples I have seen. Any help would be appreciated.
I think is because you want to use a middleware and not a route, so maybe your code can be write in this way:
var express = require('express');
var app = express();
app.use(function(err, request, response, next) {
if (error) {
request.status(403);
return next();
}
});
app.get("/test", function(request, response, next) {
response.set("Content-Type", "text/html; charset=UTF-8");
var id = request.query.snuid;
var currency = request.query.currency;
var mac_address = request.query.mac_address;
var display_multiplier = request.query.display_multiplier;
//
response.status(200).end();
});
// Listen on port 8000, IP defaults to 127.0.0.1
var server = app.listen(8000, function() {
console.log("node express app started at http://localhost:8000");
});`
I'm working on creating a middleware for an express router that will execute some code for every request and response. Intercepting a request is easy and there are plenty of examples, but I have not found anything for an elegant approach to intercepting a response. After some research, the best I have come up with is to replace the send function of the response object, shown in the following snippet:
const express = require('express');
const app = express();
var router = express.Router();
var port = process.env.PORT || 3000;
router.get('/test', function(req, res) {
res.send({
message: "testing"
});
});
app.use(function(req, res, next){
console.log("INTERCEPT-REQUEST");
const orig_send = res.send;
res.send = function(arg) {
console.log("INTERCEPT-RESPONSE");
orig_send.call(res, arg);
};
next();
});
app.use("/api", router);
app.listen(process.env.PORT || 3000) && console.log("Running");
There's a problem with this approach: for some reason "INTERCEPT-RESPONSE" is printed in the console twice, meaning res.send is being called twice...
I can set a flag on res.locals the first time it's called to avoid processing the response twice, but I am wondering why res.send is being called twice?
Better example
Try this code to see what are the arguments passed to res.send:
const express = require('express');
const app = express();
var router = express.Router();
var port = process.env.PORT || 3000;
router.get('/test', function(req, res) {
console.log('ACTUAL RESPONSE');
res.send({
message: "testing"
});
});
app.use(function(req, res, next){
console.log("INTERCEPT-REQUEST");
const orig_send = res.send;
res.send = function(arg) {
console.log("INTERCEPT-RESPONSE", JSON.stringify(arguments));
orig_send.call(res, arg);
};
next();
});
app.use("/api", router);
app.listen(process.env.PORT || 3000, function () {
console.log("Running");
});
(I also changed the printing of "Running" to print it when the server is actually listening - your code && was printed before the server was listening - but that's not that important here).
Now after running:
curl http://localhost:3000/api/test
the output on the server console is:
Running
INTERCEPT-REQUEST
ACTUAL RESPONSE
INTERCEPT-RESPONSE {"0":{"message":"testing"}}
INTERCEPT-RESPONSE {"0":"{\"message\":\"testing\"}"}
What happens
As you can see your handler is actually called once by your code, with an object as the first (and only) argument. But then it is called once again with an object serialized to JSON. This is how res.send internally works - see below for details. Since you put your intercepting function on the actual response object then I guess it is calling itself with JSON argument and it doesn't even know that it calls your function in the meantime.
How to avoid it
Try it with the object serialized to JSON by yourself:
const express = require('express');
const app = express();
var router = express.Router();
var port = process.env.PORT || 3000;
router.get('/test', function(req, res) {
console.log('ACTUAL RESPONSE');
res.send(JSON.stringify({
message: "testing"
}));
});
app.use(function(req, res, next){
console.log("INTERCEPT-REQUEST");
const orig_send = res.send;
res.send = function(arg) {
console.log("INTERCEPT-RESPONSE", JSON.stringify(arguments));
orig_send.call(res, arg);
};
next();
});
app.use("/api", router);
app.listen(process.env.PORT || 3000, function () {
console.log("Running");
});
Now it prints:
Running
INTERCEPT-REQUEST
ACTUAL RESPONSE
INTERCEPT-RESPONSE {"0":"{\"message\":\"testing\"}"}
Calling the res.send only once.
Explanation
Now, this is the code that handles object arguments to res.json:
if (chunk === null) {
chunk = '';
} else if (Buffer.isBuffer(chunk)) {
if (!this.get('Content-Type')) {
this.type('bin');
}
} else {
return this.json(chunk);
}
See: https://github.com/expressjs/express/blob/master/lib/response.js#L144-L154
You get the else branch and it calls this.json() (which is res.json() really) with your argument.
But guess what - res.json() calls res.send() in this line:
return this.send(body);
See: https://github.com/expressjs/express/blob/master/lib/response.js#L250
Which calls your intercepting function (for the second time) before running the real res.send().
So, mystery solved. :)
I need to capture de sended data. I know how to set a middleware and capture the request and the response header.
I'm asking for capture the sent data.
I'm trying this:
var express = require('express')
var app = express();
var onFinished = require('on-finished')
app.listen(3000);
function logRes(res){
console.log('* captured response *')
console.log(res._header)
console.log(res.statusCode)
console.log(res.statusMessage)
console.log(res.body) // THIS DOES NOT WORKS!
}
app.use(function(req,res,next){
onFinished(res, function (err, res) {
logRes(res)
})
console.log('= captured request =');
console.log(req.method)
console.log(req.path)
console.log(req.query)
next();
});
app.get('/example',function(req,res){
res.header('Content-Type','text/plain');
res.end('example data');
});
Can any says to me how to look at the sent data in the line with the // THIS DOES NOT WORKS! comment?
You first need to include the third party middleware body-parser:
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.listen(3000);
app.use(bodyParser.json({ type: 'application/*+json' }));
app.use(function(req,res,next) {
console.log('= captured request =');
console.log(req.method);
console.log(req.path);
console.log(req.query);
console.log(req.body);
next();
});
app.get('/example',function(req,res) {
res.header('Content-Type','text/plain');
res.end('example data');
});
Check the repo and documentation here.
I'm retrieving a web address as a URL parameter and then displaying whether the address returns a status code of 200 or not. The trouble is, it seems to only work after a couple seconds--the first time I run it, the code assigning 'mystatus' doesn't seem to be working properly. I feel like there is an issue with the order in which I am running things, but I'm not sure how to fix it.
var express = require("express");
var moment = require("moment");
var http = require("http");
var express = require("express");
var moment = require("moment");
var http = require("http");
var app=express();
var mystatus="";
app.get('/new/:name*', function(req,res){
//detect if name is a URL
//return output
http.get("http:"+req.params[0], function(thisres){
if (thisres.statusCode != 200){
mystatus = "Could not load";
}
else {
mystatus = "Loaded!";
}
}).on('error', function(e){
console.error(e);
})
res.json({url_part1: req.params.name,
url_part2: req.params[0],
status: mystatus
});
})
app.listen(8080, function(){
console.log("App listening on port 8080")
});
You're running your code node in the promise, so both http.get and res.json are running at the exact same time, so whichever one finishes first it doesn't matter.
Move the res.json response into the promise body of http.get so it will send the response when it gets it
var express = require("express");
var moment = require("moment");
var http = require("http");
var express = require("express");
var moment = require("moment");
var http = require("http");
var app=express();
var mystatus="";
app.get('/new/:name*', function(req,res){
//detect if name is a URL
//return output
http.get("http:"+req.params[0], function(thisres){
if (thisres.statusCode != 200){
mystatus = "Could not load";
}
else {
mystatus = "Loaded!";
}
res.json({url_part1: req.params.name,
url_part2: req.params[0],
status: mystatus
});
}).on('error', function(e){
console.error(e);
})
})
app.listen(8080, function(){
console.log("App listening on port 8080")
});
I want to start a proxy server with node.js so that it serves requests preprended with "/wps_proxy/wps_proxy?url=". I want it so I can use the wps-js library of north52 (check the installation tips) . I have already a server where I run my application.
What I did try until now is :
the server.js file
var express = require('express');
var bodyParser = require('body-parser');
var fs = require('fs');
var path = require("path");
var app = express();
app.use(express.static(__dirname + '/' + 'public'));
var urlencodedParser = bodyParser.urlencoded({ extended: false });
//****** this is my try ******************************
app.get('/wps_proxy/wps_proxy',function (req,res){
res.sendfile(__dirname + '/' + 'public/wps_proxy/wps-js/target/wps-js-0.1.2-SNAPSHOT/example.html');
if(req.query !== undefined){//because it enters sometimes without url
var http = require('http');
//Options to be used by request
var options = {
host:"geostatistics.demo.52north.org",//fixed given data
port:"80",
path:"/wps/WebProcessingService"
};
var callback = function(response){
var dat = "";
response.on("data",function(data){
dat+=data;
});
response.on("end", function(){
res.end(dat)
})
};
//Make the request
var req = http.request(options,callback);
req.end()
}
})
var ipaddress = process.env.OPENSHIFT_NODEJS_IP||'127.0.0.1';
var port = process.env.OPENSHIFT_NODEJS_PORT || 8080;
app.set('port', port);
app.listen(app.get('port'),ipaddress, function() {
console.log( 'Server started on port ' + app.get('port'))
})
//***************************************
but its not working.. I think that the data are not sent back correctly..
This is a live example of what I want to do.. http://geoprocessing.demo.52north.org/wps-js-0.1.1/
and this is a live example of my application (check the console for errors) http://gws-hydris.rhcloud.com/wps_proxy/wps_proxy
I did find my answer from this post How to create a simple http proxy in node.js? so the way i solve it was:
app.get('/wps_proxy/wps_proxy',function (req,res){
var queryData = url.parse(req.url, true).query;
if (queryData.url) {
request({
url: queryData.url
}).on('error', function(e) {
res.end(e);
}).pipe(res);
}
else {
res.end("no url found");
}
})