I have a simple node js server like this:
var express = require('express');
var app = express();
var httpProxy = require('http-proxy');
var apiProxy = httpProxy.createProxyServer();
var serverOne = 'http://<address>:<port>/sap/opu/odata/sap/Z_ATTENDANCE_SRV/';
app.use(express.static('webapp'));
app.use(express.static('./'));
app.all("/attendance/*", function(req, res) {
console.log('redirecting to Server1: ' + serverOne);
apiProxy.web(req, res, {target: serverOne});
});
app.listen(3000);
So address localhost:3000/attendance should redirect me to http://<address>:<port>/sap/opu/odata/sap/Z_ATTENDANCE_SRV/ but it is not, I am getting 404.
I was able to make it work when I set the proxy path as "/*" instead of "/attendance/*", but when I wanted to access entity set "AttendanceSet" via localhost:3000/AttendanceSet it also gave me 404. Do I need to create proxy for all my paths? Shouldn't the /* do that?
When I check initialisation of oDataModel in SAPUI5 app I can see such a request (In this case I have set "/*" for the proxy):
Request URL: http://localhost:3000/$metadata?sap-language=EN
Request Method: GET
Status Code: 200 OK (from disk cache)
Remote Address: [::1]:3000
Referrer Policy: no-referrer-when-downgrade
By this logic, I should be able to access entity set AttendanceSet, but I guess I am missing something.
Thanks.
For urls like localhost:3000/AttendanceSet or localhost:3000/Attendance you have to remove the / you have in you endpoint like this.
app.all("/attendance*", function(req, res) {
console.log('redirecting to Server1: ' + serverOne);
apiProxy.web(req, res, {target: serverOne});
});
Looks like problem was with cache. I deleted browser cache and also, when running node js server I used addition -c-1 to do no caching.
Related
This is my first attempt at http-proxy. I am getting the error:
Error: Must provide a proper URL as target
Code:
httpProxy = require('http-proxy');
httpProxy.createServer(function(req, res) {
proxy.web(req, res, { target: 'http://127.0.0.1:10002' });
}).listen(3001);
I know from curl my website is running on port 10002.
What does a properly URL look like? Or is this error actually mean something completely different? Port 10002 is not accessible outside of the box, I am testing this over the Internet.
You need to create the server with the http module, not http-server.
Replace httpProxy.createServer with require('http').createServer :
const httpProxy = require('http-proxy')
const proxy = httpProxy.createProxyServer({}) // I added this line to make this full snippet working
require('http').createServer(function (req, res) {
proxy.web(req, res, { target: 'http://127.0.0.1:10002' })
}).listen(3001)
What I am trying to do:
Proxy a java api that runs on https://127.0.0.1:443/api/ along side my UI that runs on non-SSL http://127.0.0.1:1337/ in order to circumnavigate some CORS issues.
My attempt:
Proxy the api at the SSL port 443 to my non-SSL development port of 1338.
proxy my UI to 1337
Proxy 1137 to :8080/index.html and proxy 1338 to :8080/api/
Access my app from localhost:8080
My problem:
The UI comes in just fine... but I can not hit the API at :8080/api/httpSession/init
Yes, I can still hit the API at https://localhost/api/httpSession/init
api.js - Renders index.html at :1337
var app = express();
app.all('*', function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
});
var options = {
changeOrigin: true,
target: {
https: true
}
};
httpProxy.createServer(443, '127.0.0.1', options).listen(1338);
start.js - Proxies 1337 and 1338 into 8080
// First I start my two servers
uiServer.start(); // renders index.html at 1337
apiServer.start(); //
// I attempt to patch them back into one single non-SSL port.
app
.use('/', proxy({target: 'http://localhost:1337/'}))
.all('/api/*', proxy({target: 'http://localhost:1338/'}))
.listen(8080, function () {
console.log('PROXY SERVER listening at http://localhost:%s', 8080);
});
What you're looking for is request piping. Try this example:
// Make sure request is in your package.json
// if not, npm install --save request
var request = require('request');
// Intercept all routes to /api/...
app.all('/api/*', function (req, res) {
// Get the original url, it's a fully qualified path
var apiPath = req.originalUrl;
// Form the proxied URL to your java API
var url = 'https://127.0.0.1' + apiPath;
// Fire off the request, and pipe the response
// to the res handler
request.get(url).pipe(res);
});
Make sure to add some error handling if the api can't be reached, such as this SO solution.
For the proxy issue, my guess is that it is keeping the /api/* in the url and that's not present on the router in your API service. You could try adding /api to the router in the API service since it's going to keep the url string the same when it sends it. Otherwise, you likely need to proxy and rewrite the url so that the API will match the request to a route.
On another note, what about just installing the cors module and using in the app? I do something similar and it's working well without all the proxy items. https://www.npmjs.com/package/cors
I have in my private network different services, these services are not accessible from the out side (externe).
I'd like that my services be accessible to some users, and this after an authentication process (for this part I use express).
Once the user is authentificared it will be proxiate to the right service, I tried for this the http-proxy module.
Problem:
I failed to use correctly http-proxy with express module, and resolve this enigma as wished.
Code:
I began by doing this
// Create app with Express
var express = require('express');
var app = express();
// Create a proxy server with http-proxy
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer();
// Create target params (in the local network)
var serverOne = {target:'ws://172.17.0.3:80',ws:true};
// The use of proxy to expose the service
app.all("/app/", function(req, res) {
console.log('redirecting to Server1');
proxy.web(req, res, serverOne);
})
// The login part
.get('/login', function(req, res) {
res.render('login.ejs');
console.log('Cherche Login');
})
app.listen(8080);
Result:
Can someone help me please to fix this?
Try changing var serverOne = {target:'ws://172.17.0.3:80',ws:true};
to var serverOne = {target:'ws://172.1.0.3:80',ws:true};
Also check that from the server 104.155.15.204, you are able to access the 172.0.1.x network
You can have a look at http://expressjs.com/fr/api.html for implementation of proxies on express.
Regards,
Marc
I'm developing a web application using nodejs and I need a reverse proxy for this application.
In many places it is noticed that nginx is used as a reverse proxy.
My questions are
1. "Is there any ready made nodejs based reverse proxy?"
2. "Is it a good idea to implement a nodejs based reverser proxy?"
3. "It is advised to use nginx?"
4. Why is nginx is considered in first place for reverse proxy?
--Ganesh
use following command to install Express.js and http-proxy.
npm install --save express http-proxy
In order to run the reverse proxy server we need some resource server from which Proxy will fetch data.So to do that, develop three Express server running on Port 8000,8001,8002 respectively.
Server.js
var express = require("express");
var app = express();
app.get('/app1',function(req,res) {
res.send("Hello world From Server 1");
});
app.listen(8000);
write the same code for other servers too and change the text.
Example of proxy server code in express.js with multiple targets.
app.js (file)
var express = require('express');
var app = express();
var httpProxy = require('http-proxy');
var apiProxy = httpProxy.createProxyServer();
var serverOne = 'http://localhost:8000',
ServerTwo = 'http://localhost:8001',
ServerThree = 'http://localhost:8002';
app.all("/app1/*", function(req, res) {
console.log('redirecting to Server1');
apiProxy.web(req, res, {target: serverOne});
});
app.all("/app2/*", function(req, res) {
console.log('redirecting to Server2');
apiProxy.web(req, res, {target: ServerTwo});
});
app.all("/app2/*", function(req, res) {
console.log('redirecting to Server3');
apiProxy.web(req, res, {target: ServerThree});
});
app.listen(8000);
You can add as many targets as you want and it will create a proxy for that.Check whether its working or not by first run all the servers and hit request to /app1 and /app2 etc.
I found the DProx node plugin an absolute must. Allows for most of the configuration that one would need from a Reverse proxy server, while making it simple JSON config.
im trying to proxy requests from a secure web application(https) in node (its an internal application) and im not quite sure how to do it...
the below is my code which works when i try it from an non secured app (http).
It just strips out a page name and uses it in another app. I read the docs but still not sure how to do it. Do i need to have the ssl info from my application for this to work?
var http = require('http');
var httpProxy = require('http-proxy');
var request = require('request');
var app = require('express.io')();
app.http().io();
//
// Create proxy server
//
var proxy = httpProxy.createProxyServer({target:'http://localhost:9000'}).listen(9085);
// Send the client html.
app.get('/', function(req, res) {
res.sendfile(__dirname + '/client1.html');
})
proxy.on('error', function (err, req, res) {
res.writeHead(500, {
'Content-Type': 'text/plain'
});
res.end('Something went wrong!');
});
app.all('/Domain/*', function(req, res) {
console.log(req.url);
if (req.url.indexOf("Page.do") > -1) {
// URL to Atlas
var otherAppURL = "http://myotherapp/pages/";
var temp = req.url.split("Page.do")[0].split("/");
var pageName = temp[temp.length - 1];;
app.io.broadcast('update', {
url: atlasURL + pageName + '.html'
});
};
// This doesnt work
//var url = "https://mysecureapp:9044" + req.url;
// This works
var url = "http://localhost:9080" + req.url;
req.pipe(request(url)).pipe(res);
})
app.listen(9000);
Yes, you do need an SSL Certificate for an HTTPS connection. According to the website https://www.globalsign.com/en/ssl-information-center/what-is-an-ssl-certificate/ :
The standard HTTP is changed to HTTPS, automatically telling the browser that the connection between the server and the browser must be secured using SSL.
This means that with an HTTPS connection, you need to have the server secured with SSL.
For connecting with HTTPS in Node, this website might help you:
http://gaboesquivel.com/blog/2014/nodejs-https-and-ssl-certificate-for-development/
Ok i might be mistaking but this line doesn't make sense ,
req.pipe(request(url)).pipe(res);
by the time the route handler hits, the req object is ready
so req.pipe has no meaning.
please check that url returns a valid response
request(url).pipe(res); should work
http / https is not an issue