I'd like to clone/relay the exact request to another URL in native NodeJs. For example, if you send a POST request to my site "example.com", it will send the exact same request you sent to another URL "example2.com" (data, headers etc). How could I achieve that?
You can use proxy middleware to duplicate the request. For example http-proxy-middleware will allow you to proxy the request to another server, but from what I can tell, you can only modify the response. Which isn't optimal if you don't want to wait on the proxy. You might just grab the main proxy library itself, something like:
const httpProxy = require('http-proxy');
const proxyMiddleware = httpProxy.createProxyMiddleware({
target: 'http://www.example2.com',
selfHandleResponse: true
});
const customProxyMiddleware = (req, res, next) => {
proxy.web(req, res);
next();
};
// This passes all incoming requests to the proxy but does not handle
// any of them. It simply passes it along.
app.use('/', customProxyMiddleware);
This code may not work exactly as intended but it should be a good starting point for what you are attempting.
Related
I am trying to setup a very simple nodeJS HTTP server. When I call it from the browser, like this http://localhost:8081, it works fine, but when I call is using a JS fetch() method, I get a 404 error:
GET http://localhost/:8081?q=hi
JS:
fetch(":8081/?q=hi")
NODE JS:
const requestListener = function (req, res) {
res.writeHead(200);
res.end('Hello, World!');
}
const server = http.createServer(requestListener);
server.listen(8081);
Every thing is fine, you just need to enable cors that's it, use the below code
const http = require('http')
const requestListener = function (req, res) {
const headers = {
'Access-Control-Allow-Origin': '*', /* #dev First, read about security */
'Access-Control-Allow-Methods': 'OPTIONS, POST, GET',
'Access-Control-Max-Age': 2592000, // 30 days
/** add other headers as per requirement */
};
res.writeHead(200, headers);
res.end(JSON.stringify({"key":"value"}));
}
const server = http.createServer(requestListener);
server.listen(8081);
If you are running both frontend and backend code on the same server then you don’t have to use complete url while if you are running fronted and backed on different server you need to enable cors and use complete url.
When you're calling your local server through JS fetch, you don't need to add the port number you can call it like below:
fetch('/?q=hi')
the URL handed to fetch function looks wronge, it would work if you adjust it to:
fetch('http://localhost:8081/?q=hi');
// or
fetch('/?q=hi');
it should work just fine,
and ensure that you enable the cors if you need to works from any domain
Here in the GET /facebook route i receive the authorization code from front-end after receiving that, i have to make a POST request to /facebook/signin
How can I redirect GET /facebook to POST /facebook/signin
router.get('/facebook', (req, res) => {
// res.send(req.query.code);
res.redirect('/facebook/sign'); // = GET /facebook/sign
});
POST route
router.post('/facebook/sign', (req, res, next) => {
console.log(req.query.code);
// i will do mine stuff....
});
You can also write 1 handler method and use it in both routes;
function doFacebookSignIn(req, res) {
// Your code here.
}
or
// Must be defined before using it in code.
var doFacebookSignIn = function(req, res) {
// Your code here.
};
router.get('/facebook', doFacebookSignIn);
router.post('/facebook/sign', doFacebookSignIn);
But as I pointed out in the comments, you should be aware that when using a request body in a GET request, there are some things to consider.
You cannot redirect GET to POST, a redirect is used to notify an HTTP client that a resource has changed location and should attempt the same request using the new location.
It is noted in the RFC that in some cases POST will be downgraded to GET when the request is re-issued.
Note: When automatically redirecting a POST request after
receiving a 301 status code, some existing HTTP/1.0 user agents
will erroneously change it into a GET request.
If a POST request is expected on the server, then the client should send a POST request rather than a GET request.
Is there any way to tamper with the data that socket.io sends just before it is sent/received? I was thinking about something like an express middleware.
So that I could encode data after the normal .emit() method is called and before socket.on(...) is called.
In express I would imagine it to look somewhat like this to BISON decode all incoming request:
app.use(function(req, res, next) {
req.body = BISON.decode(req.body);
next();
});
Now how could that be done with socket.io in a way that requests being sent also get encoded automatically?
I know that socket.io supports middlewares in a similar form to express, but that is only for the actual http request that socket.io sends to create the websocket connection...
io.use(function(socket, next) {
//...
next();
});
so I doubt that this would be of any help here..
You can intercept (and change) data by listening for packet events, and similarly use the flush event to intercept outgoing messages:
io.use(function(socket, next) {
socket.conn.on('packet', function(packet) {
...change `packet.data` here...
});
socket.conn.on('flush', function(packets) { // array of packets
...
});
next();
});
But to be honest, I'm having a hard time finding documentation on how packet.data is encoded, so I can't provide a full example.
EDIT: socket.io-parser has decodeString() which is used to parse the payload. Sadly, it's not exported (and the methods that are exported are all async, which doesn't combine well with event handlers).
I am concerned about security of my react/redux application as my api url is exposed to the public inside bundled app.js file. I've been researching this and some developers proxy it somehow i.e. instead of using my api url I can use api/ whenever I perform calls with libraries like axios or superagent and it gets proxied to my api url, but this way users can only see api/ on their side.
I'm trying to figure this out, I assume this is set up within express config?
You have a valid concern.
Typically you would have your clientside code make calls to, say, /api, and in express (or whatever server you use) create a route for "/api" that proxies that request to the actual api url.
This way you can obscure any sensitive information from the client. For example authentication tokens, api keys, etc.
In express you could do something like this:
app.use('/api', (req, res) => {
const method = req.method.toLowerCase();
const headers = req.headers;
const url = 'your_actual_api_url';
// Proxy request
const proxyRequest = req.pipe(
request({
url
headers,
method,
})
);
const data = [];
proxyRequest.on('data', (chunk) => {
data.push(chunk);
});
proxyRequest.on('end', () => {
const { response } = proxyRequest;
const buf = Buffer.concat(data).toString();
res.status(response.statusCode).send(buf);
});
});
This example is a bit more elaborate that is has to be, but it will probably work for you.
How do i let node.js act as a proxy and forward all requests sent from one server to another server but stripping /couchdb/ from the url path so that for example POST /couchdb/mydatabase will be POST /mydatabase. And when it receives the response it should send it to the first server.
All I have done is this (using express) to get all requests where the URL path starts with /couchdb/
app.all(/^\/couchdb\/(?:.)*/, function(req, res) {
});
Could someone guide me through. Thanks
have a look at node-http-proxy. you can use it like this:
var http = require('http'),
httpProxy = require('http-proxy');
httpProxy.createServer(function (req, res, proxy) {
// Put your custom server logic here (eg rewrite url/header,...)
proxy.proxyRequest(req, res, {host: 'localhost', port: 9000});
}).listen(8000);