Express JS wild card route proxying - javascript

I am using express-http-proxy to proxy a backend server.
I would like all requests to /proxy viz /proxy/apples/brand or /proxy/oranges/brand/nnnn etc to be proxied to the backend service.
So, I have a wild card proxy set up here.
'use strict';
var express = require('express');
var proxy = require('express-http-proxy');
var app = express();
// ""
app.use('/proxy*', proxy('https://backend-server.com/' ,{
forwardPath: function(req, res) {
console.log(req.url)
return require('url').parse(req.url).path;
}
}));
var port = 3000;
app.listen(port, function() {
console.log('listening on port ' + port + '.')
});
I expect this
https://localhost:3000/proxy/oranges/brand/nnnn to be proxied to https://backend-server.com/oranges/brand/nnnn
But I just get
Cannot GET /proxy/aa
.I am not sure what's wrong here. The wild card routing looks pretty ok. Any thoughts here?

You could try request module. This solution perfectly works for me
var request = require( 'request' );
app.all( '/proxy/*', function( req, res ){
req.pipe( request({
url: config.backendUrl + req.params[0],
qs: req.query,
method: req.method
}, function( error, response, body ){
if ( error )
console.error( 'Wow, there is error!', error );
})).pipe( res );
});
Or if you still want to use express-http-proxy you need to write
app.use( '/proxy/*', proxy('https://backend-server.com/', {
forwardPath: function( req, res ){
return req.params[0];
}
}));

Related

node.js: The POST method in my RESTAPI does not work

I start learning Node.js and Express.js and I'm trying to create a simple API to list data from JSON file (using the GET method) and add a new user using the POST method.
the GET method works fine but the POST method does not work
when I request http://127.0.0.1:8080/listusers the API sends all users in a JSON file.
when I request http://127.0.0.1:8080/adduser the API has to add new User Info and send the new data back to the browser.
NOTE: I read all the questions on Stackoverflow about this problem but
non of them help me so I have to ask again.
the problem is when I request http://127.0.0.1:8080/adduser I get the following error
Cannot GET /adduser
here is the server.js:
var express = require('express');
var app = express();
var fs = require('fs');
var user = {
"user4" : {
"name" : "mounir",
"password" : "password4",
"profession" : "teacher",
"id": 4
}
};
app.post('/adduser', function (req, res) {
// First read existing users.
fs.readFile( __dirname + "/" + "users.json", 'utf8', function (err, data) {
data = JSON.parse( data );
data["user4"] = user["user4"];
console.log( data );
res.end(JSON.stringify(data) );
});
});
app.get('/listusers', function (req, res) {
fs.readFile( __dirname + "/" + "users.json", 'utf8', function (err, data) {
console.log(data);
res.end(data);
});
});
var server = app.listen(8080, function () {
var host = server.address().address;
var port = server.address().port;
console.log("listening at http://%s:%s", "0.0.0.0", port)
});
The answer is in the error. Cannot GET /adduser. Keyword GET! If you are making a post request, be sure you include the appropriate headers and that you are making a POST request, with a body, and not a GET request. For instance if you are using fetch:
const myInit = {
method: 'POST',
headers: myHeaders,
body: {
...
}
};
fetch("http://127.0.0.1:8080/adduser", myInit)
.then(res => {
...
});

pass value from input to node js http request parameter

greeting kings
i have api request that have cors problem. I'm able to solve by using proxy setup using nodejs. Unfortunately im trying to pass certain query parameter from my main js to app.js(nodejs proxy) so my api can have certain value from main js. How to solve this or should point me where should i read more.below is my code
main js
const inputValue = document.querySelector('input').value
//this value is maybeline
app.js(node.js proxy)
const express = require('express')
const request = require('request');
const app = express()
app.use((req,res,next)=>{
res.header('Access-Control-Allow-Origin', '*');
next();
})
app.get('/api', (req, res) => {
request(
{ url: 'https://makeup-api.herokuapp.com/api/v1/products.json?brand=covergirl' },
(error, response, body) => {
if (error || response.statusCode !== 200) {
return res.status(500).json({ type: 'error', message: err.message });
}
res.json(JSON.parse(body));
}
)
});
const port = process.env.PORT || 5500
app.listen(5500,()=>console.log(`listening ${port}`))
I want to pass inputValue as query to api in app.js
as
https://makeup-api.herokuapp.com/api/v1/products.json?brand=${type}
How to do it or point me any direction?
note:this api work withour cors problem.This is an example api..tq
You can use stringify method from qs module.
const { stringify } = require("qs");
app.get("/api", (req, res) => {
request(
{
url: `https://makeup-api.herokuapp.com/api/v1/products.json?${stringify(
req.params
)}`,
}
/// Rest of the code
);
});

Node.js and ExpressJS body-parser package retrieve data

OK first time user of Node, and I am trying to send data to backend/index.js
Requirements
Post data to back-end node
Retrieve posted data and store values as variables
Whats the problem
The post is 200 success, that works.
however when I navigate to :
http://localhost:8080/backend/index
I get :
Cannot GET /backend/index
Where am I going wrong ?
Here is my front end post post
var settings = {
"async": true,
"crossDomain": true,
"url": "http://localhost:8080/backend/index.js",
"method": "POST",
"headers": {
"content-type": "application/x-www-form-urlencoded"
},
"data": {
"id": "1223",
"token": "223",
"geo": "ee"
}
}
$.ajax(settings).done(function (response) {
console.log(response);
});
I am trying to retrieve this data from and store as variable in the back end node.
backend/index.js
// grab the packages we need
var express = require('express');
var app = express();
var port = process.env.PORT || 8080;
// routes will go here
// start the server
app.listen(port);
console.log('Server started! At http://localhost:' + port);
var bodyParser = require('body-parser');
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
// POST http://localhost:8080/api/users
// parameters sent with
app.post('/backend/index', function(req, res) {
var user_id = req.body.id;
var token = req.body.token;
var geo = req.body.geo;
res.send(user_id + ' ' + token + ' ' + geo);
});
UPDATE using screen shots
I think you didn't specify GET method, you can do like this
app.get('/', function(req, res) {
res.send('do something 1');
});
app.get('/backend/index', function(req, res) {
res.send('do something 2');
});
Hope this will help!
Because you Post Api and you can not get result without parameter.
Your Post Api will not give output until you hit only url on web browser, so need postman for Post Api.
Now you get Output without any problem.
Thanks in Advance

Body of request comes back as object when sending string request using $http.post (angular) and bodyparser.text()?

When I send a string value as the request, the req.body value is an object. I am using:
I have a factory cust1_service.postQuery:
.factory('cust1_service', function($http){
return {
postQuery : function(request){
console.log('cust1 req : ' + request);
console.log('typeof request : ' + typeof request);
var config = {'Content-Type' : 'text/plain'};
return $http.post('/cust1', request);
}
}
Here is how I call the factory in my controller:
cust1_service.postQuery(req_string).success(handleSuccess);
I am also using bodyParser.text() before my routes
var express = require('express'),
config = require('./config/config'),
bodyParser = require('body-parser'),
api = require('./app/routes/api.js');
var app = express();
app.use(bodyParser.text({
type: "text/*"
}));
app.use(express.static(__dirname + '/public')); //Serve static assets
require('./app/routes/api.js')(app, db);
app.listen(config.port, function() {
console.log('Listening on ' + config.port);
})
So....when I get to my routing api
app.route('/cust1')
.post(function(req,res){
console.log('this is req.body : ' + req.body);
req.body is [object Object]...am I sending the request as a text type incorrectly?? I need req.body to be a string.
Try to "stringify" the req.body to be sure if it's still passed as a JSON object. You can also try logging the console like console.log('this is req.body : ', req.body, ' --- ');
One solution you can try is to completely remove the use of the BodyParser middleware - this should force the body to be text.
SO you need to remove or comment out the line:
app.use(bodyParser.text({ type: "text/*"}))
You can look at a closely related question here.
I hope this helps;

Edit POST parameters prior to forwarding to a proxy target and sending response back to client

I have a node/express proxy setup using http-proxy-middleware to route requests to a java-tomcat web service (proxy target).
I need to inject POST form data into the request rawbody with a context-type of "application/x-www-form-urlencoded" prior to forwarding the request to the proxy target. The proxy response will need to have the same post parameters removed prior to sending the response to the client.
I have used a number of different proxies include http-proxy, http-proxy-middleware, node-proxy, and express-proxy but none of these modules appear to have a solution available that allows for POST parameter manipulation
This question was originally posted on
https://github.com/chimurai/http-proxy-middleware/issues/61#issuecomment-205494577
'use strict';
var express = require('express');
var router = express.Router();
//var request = require("request");
var proxy_filter = function (path, req) {
return path.match('^/report') && ( req.method === 'GET' || req.method === 'POST' );
};
var proxy_options = {
target: 'http://localhost:8080',
logLevel: 'debug',
//logProvider:
onError(err, req, res) {
res.writeHead(500, {
'Content-Type': 'text/plain'
});
res.end('Something went wrong. And we are reporting a custom error message.' + err);
},
onProxyRes(proxyRes, req, res) {
//proxyRes.headers['x-added'] = 'foobar'; // add new header to response
//delete proxyRes.headers['x-removed']; // remove header from response
},
onProxyReq(proxyReq, req, res) {
if ( req.method == "POST" && req.body ) {
proxyReq.write( encodeURIComponent( JSON.stringify( req.body ) ) );
proxyReq.end();
}
}
};
// Proxy configuration
var proxy = require( 'http-proxy-middleware' )( proxy_filter, proxy_options );
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Node.js Express Proxy Test' });
});
router.all('/report/*', function( req, res, next ) {
//req.body.jdbc_sas = 'jdbc:postgresql://pg_dev:5432/sasdb';
//req.body.jdbc_agency = 'jdbc:postgresql://pg_dev:5432/agency0329';
//console.log('proxy body:',req.body);
proxy( req, res, next );
} );
module.exports = router;
Any suggestions are greatly appreciated.
Respectfully,
Warren.
Ok Here's the final solution.
The following example allows you to inject POST parameters prior to forwarding to the proxy target. You don't have scrub any parameters from the proxy target response - as far as I can tell - because it maintains a copy of the original POST request.
On a side note this also allows the http-proxy-middleware to work with body-parser.
Example Node Express Route File:
'use strict';
var express = require('express');
var router = express.Router();
var proxy_filter = function (path, req) {
return path.match('^/docs') && ( req.method === 'GET' || req.method === 'POST' );
};
var proxy_options = {
target: 'http://localhost:8080',
pathRewrite: {
'^/docs' : '/java/rep/server1' // Host path & target path conversion
},
onError(err, req, res) {
res.writeHead(500, {
'Content-Type': 'text/plain'
});
res.end('Something went wrong. And we are reporting a custom error message.' + err);
},
onProxyReq(proxyReq, req, res) {
if ( req.method == "POST" && req.body ) {
// Add req.body logic here if needed....
// ....
// Remove body-parser body object from the request
if ( req.body ) delete req.body;
// Make any needed POST parameter changes
let body = new Object();
body.filename = 'reports/statistics/summary_2016.pdf';
body.routeid = 's003b012d002';
body.authid = 'bac02c1d-258a-4177-9da6-862580154960';
// URI encode JSON object
body = Object.keys( body ).map(function( key ) {
return encodeURIComponent( key ) + '=' + encodeURIComponent( body[ key ])
}).join('&');
// Update header
proxyReq.setHeader( 'content-type', 'application/x-www-form-urlencoded' );
proxyReq.setHeader( 'content-length', body.length );
// Write out body changes to the proxyReq stream
proxyReq.write( body );
proxyReq.end();
}
}
};
// Proxy configuration
var proxy = require( 'http-proxy-middleware' )( proxy_filter, proxy_options );
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Node.js Express Proxy Test' });
});
router.all('/document', proxy );
module.exports = router;

Categories

Resources