chimurai / http-proxy-middleware

:zap: The one-liner node.js http-proxy middleware for connect, express, next.js and more
MIT License
10.7k stars 834 forks source link

NextJS: API resolved without sending a response for /xx/xx, this may result in stalled requests. #795

Closed anonymouscatcher closed 1 year ago

anonymouscatcher commented 2 years ago

Checks

Describe the bug (be clear and concise)

I'm trying to setup local proxy while it's working fine for all the requests, it doesn't work for POST requests including data. I have disabled bodyParser but it didn't help.

I also created an issue about this but it doesn't seems to be next.js issue but I'm not sure. Issue: https://github.com/vercel/next.js/issues/36811 Discussion: https://github.com/vercel/next.js/discussions/36859

Step-by-step reproduction instructions

1. create api in next project
2. send a post request including data (like a login api)
3. you will see that the request won't be resolved

Expected behavior (be clear and concise)

I expect to resolve the api with a response.

How is http-proxy-middleware used in your project?

=> Found "http-proxy-middleware@2.0.6"
info Has been hoisted to "http-proxy-middleware"
info This module exists because it's specified in "devDependencies".
info Disk size without dependencies: "184KB"
info Disk size with unique dependencies: "592KB"
info Disk size with transitive dependencies: "2.83MB"
info Number of shared dependencies: 11
✨  Done in 0.44s.

### What http-proxy-middleware configuration are you using?

```typescript
const proxy = createProxyMiddleware({
      logLevel: 'debug',
      target: 'XXX',
      changeOrigin: true,
      autoRewrite: true,
    });

export default proxy;

What OS/version and node/version are you seeing the problem?

macOS, node 16

Additional context (optional)

No response

chimurai commented 2 years ago

Could you provide a minimal reproduction of the issue?

anonymouscatcher commented 2 years ago

@chimurai Here you go, https://github.com/alirezavlz/next-proxy-issue run the app on dev mode and run the server.js, you will see that get request is working but post request doesn't work. it stucks in pending.

image
anonymouscatcher commented 2 years ago

@chimurai could you have a look to repo? :)

chimurai commented 2 years ago

Could you provide a minimal reproduction of the issue?

I'm not really a Next.js user. Had a quick look and do see the POST is "hanging".

Are you able to recreate this issue with a minimal setup? A simple express + http-proxy-middleware and a basic POST request?

To isolate a Next.js configuration/integration issue from http-proxy-middleware issue/bug.

chimurai commented 2 years ago

With a simple express proxy server I'm able to proxy to your target server.

const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');

const app = express();

app.use(createProxyMiddleware({
    target: 'http://localhost:9090'
}));

app.listen(3000, () => {
    console.log('Server started and listening on port 3000')
});
curl -XPOST 'http://localhost:3000/api2/login'

$ {"response":"I should be returned as a response","data":{}}
anonymouscatcher commented 2 years ago

Yeah it’s so weird I’m not sure it’s an issue of next js or this library, but if I create the proxy externally it will work fine. (Not in the /api directory in next js) 😞

anonymouscatcher commented 2 years ago

I have tested the same logic with https://github.com/http-party/node-http-proxy and it worked correctly. so I think the issue should be with http-proxy-middleware.

chimurai commented 2 years ago

Can you share minimal working code with node-http-proxy? Issue can be investigated, you can recreated it with a curl command firing requests to the server. (without react)

anonymouscatcher commented 2 years ago

@chimurai I'm currently using this version of node-http-proxy which is for next js. but It uses that in top of that.

https://github.com/stegano/next-http-proxy-middleware

const proxy = (req, res) => {
  return httpProxyMiddleware(req, res, {
    target: process.env.DEFAULT_API_ENDPOINT,
    onProxyInit,
    cookieDomainRewrite,
    changeOrigin: true,
    pathRewrite: [
      {
        patternStr: '^/api/json',
        replaceStr: ''
      }
    ]
  });
};

export default proxy;

There is nothing fancy in the code it's just these couple of lines.

JacerOmri commented 1 year ago

I was stuck with this for a while. I was able to solve it using API config (in Next.js), I had to disable bodyParser.

export const config = {
  api: {
    externalResolver: true,
    bodyParser: false, // I added this
  },
jag-ermeister commented 1 year ago

I was stuck with this for a while. I was able to solve it using API config (in Next.js), I had to disable bodyParser.

export const config = {
  api: {
    externalResolver: true,
    bodyParser: false, // I added this
  },

Just in case anybody is unable to read like me, I originally misinterpreted this and added bodyParser: false to the middleware configuration, which did not help. Adding this to the Next.js API config like @JacerOmri mentioned was the fix!

chimurai commented 1 year ago

Updated the Next.js recipe.

Thanks for sharing the solution!