I am trying to debug a proxy in Express, using http-proxy-middleware, but no matter what I do I get absolutely zero response. The endpoint sends the response but it is never returned by the proxy and the onProxyRes event is never triggered. Also the endpoint can be accessed directly through curl, Insomnia, fetch API and request-promise and is in use as an API for our customers.
Even with a setup as simple as:
app.use('/api', proxy({
target: 'https://my.secret.endpoint',
changeOrigin: true
});
I get absolutely zero response, except for a ECONNRESET after timeout. Any suggestions?
Heureka! I found the answer I was looking for! The offending party was (in my case) the express.urlencoded() middleware, which does some trickery that ultimately messes up the proxy. This can be resolved by applying the offending middleware after the proxy. Other middleware that might do this include cookie-parserand bodyParser (both of which are deprecated).
More on the issue here: https://github.com/chimurai/http-proxy-middleware/issues/40
Another solution for anyone coming here with the same issue but did not solve it.
In proxy configuration make sure you are matching any path
with double ** not only *
const proxy = require("http-proxy-middleware");
module.exports = function(app) {
app.use(proxy("/api/**", { // https://github.com/chimurai/http-proxy-middleware
target: "http://localhost:5000",
secure: false
}));
};
For more check this reference
ViggoV
You need to disable the SSL when the target is https.
Like as this:
app.use('/api', proxy({
target: 'https://my.secret.endpoint',
changeOrigin: true,
secure: false
});
Related
I have CORS globally configured like this, to handle credentials:
app.use(cors({ origin: 'https://example.com', credentials: true }))
But on certain routes, I need to allow options requests, so following the documentation, I'm doing something like this:
router.options('/someroute', cors())
router.get('/someroute', cors(), someOtherMiddleware, async (req, res) => {
// do stuff
}
My global CORS policy seems to override the route policy, but only on the options method, I think. I'm trying to come up with a way to make both of these CORS policies play nicely. I have also tried the following, but this doesn't work either. Whichever one I put first seems to override the other one.
app.options('*', cors())
app.use(cors({ origin: 'https://example.com', credentials: true }))
The reason my 2nd code snippet above wasn't working as expected was because I needed to add the preflightContinue property when setting the cors policy at the app level. Otherwise it will ignore cors policies on options routes set at the route level. Kind of a poorly documented thing.
The final solution was to do this at the app level:
app.use(cors({
origin: 'https://example.com',
credentials: true,
preflightContinue: true,
}))
Now this cors policy on the options route actually works:
router.options('/someroute', cors())
router.get('/someroute', cors(), someOtherMiddleware, async (req, res) => {
// do stuff
}
Ugh, spent so long figuring this one out. Hope this saves someone some time.
I am using http-proxy-middleware to proxy hosts in my React project.
Below is the code from setupProxy.js file:
const {createProxyMiddleware} = require('http-proxy-middleware');
module.exports = function(app) {
app.use('/api', createProxyMiddleware({ target: 'http://localhost:8080', changeOrigin: true, }));
app.use('/api/user/logout', createProxyMiddleware({ target: 'http://localhost:9091', changeOrigin: true, }))
};
As you can see I added two proxy codes. For the logout, I want to use a different host. /api is working fine, but the /api/user/logout is not working.
Thanks in advance.
Because when the request goes to '/api/user/logout'.
app.use('/api') finds '/api' in the url and it fits the condition of the first app.use
You need to use regExp
app.use(/\/api\/?$/, createProxyMiddleware())
I am trying to configure a proxy for my API requests using http-proxy-middleware, which the create react app docs suggest. I set up my proxy like this, in the setupProxy.js file:
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {
app.use(
createProxyMiddleware("/post", {
target: 'https://postman-echo.com',
changeOrigin: true,
logLevel: 'debug'
})
);
};
then, I do a simple POST to an endpoint:
const response = await fetch("/post", {
method: 'POST',
headers: {
'content-type': 'application/json;charset=UTF-8'
},
body: JSON.stringify({ foo1: "bar1", foo2: "bar2" })
});
console.log(await response.json());
According to the http-proxy-middleware docs, I should expect a proxy that does something like this:
[HPM] POST /post -> https://postman-echo.com/post
But instead, the debugger shows this:
[HPM] POST /post -> https://postman-echo.com
The path, /post, does not get appended to the proxy request. The target should actually be https://postman-echo.com/post. My client gets a 404 error because https://postman-echo.com on its own does not match anything on the backend.
If it did reroute correctly, I should expect the same results as a CURL request
curl -X POST -F 'foo1=bar1' -F 'foo2=bar2' https://postman-echo.com/post
{"args":{},"data":{},"files":{},"form":{"foo1":"bar1","foo2":"bar2"},"headers":{"x-forwarded-proto":"https","x-forwarded-port":"443","host":"postman-echo.com","x-amzn-trace-id":"Root=1-61200c54-7b5809be3e78040f09edcd42","content-length":"240","user-agent":"curl/7.64.1","accept":"*/*","content-type":"multipart/form-data; boundary=------------------------bb54b419e41f4a4a"},"json":null,"url":"https://postman-echo.com/post"}%
But I 404 because the path is not added. Why is the path being left out?
I created a simple app that recreates my issue. This looks similar to this issue but they are not the same (I am using the same syntax as the answer suggests).
I got it working. The problem was that I was testing with an endpoint that 404'd. I got confused because the debugger doesn't append /post to the end of the log like the docs say it should.
So I have 2 applications:
an Adonis API server accessible via http://10.10.120.4:3333
A SSR app using Nuxt.js accessible via http://10.10.120.4:80
The Nuxt.js app is accessible outside using url http://my-website.com. I have axios module with this config
axios: {
baseURL: '0.0.0.0:3333/api',
timeout: 5000
}
Now the problem is, when I am requesting data with asyncData it works, but when the request was made from outside asyncData, say created() for example, it throws an error saying the url http:0.0.0.0:3333 is missing which is true since it's already running in the browser and not in the server.
The first solution that I've tried is to change the baseURL of the axios module to this
axios: {
baseURL: 'http://my-website.com/api',
timeout: 5000
}
But it seems nuxt server can't find it, so I think the solution is to make proxy and installed #nuxtjs/proxy.
And this is my proxy config in nuxt.config.js
{
proxy: {
'/api': 'http://my-website.com:3333',
}
}
and then I just changed my axios baseURL to
http://my-website.com/api
But again it didn't work.
My question is, how do you deal with this kind of scenario? Accessing different server from browser?
When using Proxy in a nuxt project you need to remove baseUrl and set proxy to true as seen below.
axios: {
// Do away with the baseUrl when using proxy
proxy: true
},
proxy: {
// Simple proxy
"/api/": {
target: "https://test.com/",
pathRewrite: { "^/api/": "" }
}
},
when making a call to your endpoint do:
// append /api/ to your endpoints
const data = await $axios.$get('/api/users');
checkout Shealan article
When using the logger middleware which is part of Connect (as well as Express), I would like to be able to disable logging on certain requests, say by setting a flag on the response or something.
I managed to do it by saying:
res.doNotLog = true;
and then, deep in logger.js (part of the Connect module), I put
if(res.doNotLog) return;
in the right place. But of course I don't want to be modifying code in the module itself. Is there any way I can cause the same to happen without having to hack the module?
Edit:
This worked:
var app = _express.createServer();
// set 'hello' routing...note that this is before middleware
// so it won't be logged
app.get('/sayhello', function(req, res) {res.send("hey");});
// configure middleware: logging, static file serving
app.configure(function() {
app.use(_express.logger());
app.use(_express.static(__dirname + '/www'));
});
// set 'goodbye' routing...note that this is after middleware
// so it will be logged
app.get('/saygoodbye', function(req, res) {res.send("later...");});
The most obvious thing would be to put the handlers for those requests before the logger. This is easy in pure Connect, not sure how to do it in Express because a lot of the router code is shared between routes. If there were only a few such requests, you could handle them Connect-style earlier in the stack than app.router.