Home > front end >  calling server by proxy doesn't pass parameters
calling server by proxy doesn't pass parameters

Time:02-05

I have a react UI application and a .NET API server.

The react app is running locally on: http://localhost:8082/myapp

The API app is running locally on IIS on: http://foo.local.bar.com/myappapi

I want them to communicate. Since they are running on different local domains, I needed a proxy to avoid CORS issue. On my react app, I put this code on my config.development.js file:

 devServer: {
    logLevel: 'debug',
    proxy: {
      '/myappapi/api/*': {
        target: 'http://foo.local.bar.com/',
        headers: {
          Cookie: ".MyCookie=12345"
        },
        logLevel: 'debug',
        secure: false,
        changeOrigin: true,
        withCredentials: true
      }
    },
  },

Well, it works great with GET method and I indeed get data from the API server to the UI.

The problem is with POST/PUT/DELETE methods that I want to pass data - it doesn't work and I get Gateway error after a while. I know I pass the right object because it works great on production environment, the problem is only on proxy mode (locally).

Things That I've found out until now:

  • As I said, GET method works great (the data is in the URL, not in the body) so the proxy is defined correctly.
  • a POST method without parameters works fine too.
  • a POST method with parameters works fine without the proxy (Postman to the original URL in foo.local.bar, or in production mode).

This is the code in the server:

    [Route("api/mycontroller/v1")]
    [ApiController]
    public class MyController : ControllerBase
    {
        private readonly ILogger logger;
        private readonly IMyService myService;

        /// Constructor
        public MyController (IMyService myService) // When I send the POST method, I hit the breakpoint here
        {
            this.myService = myService; 
            logger = LogManager.GetCurrentClassLogger();
        }

        [HttpPost]
        [Route("PostSomething1")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status500InternalServerError)]
        public async Task<ActionResult> AddAsync(MyObjRequest myRequest)
        {
            // I never get here on proxy mode
        }

        [HttpPost]
        [Route("PostSomething2")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status500InternalServerError)]
        public async Task<ActionResult> AddAsync2()
        {
            // This one works fine - but I can't get data from UI so it doesn't help me much
        }
}

CodePudding user response:

Well, after digging the code I've found out that our system is using HPM (httpProxyMiddleware) which has a bug in early versions (search Google for "fixRequestBody"). Since It's in our inner packages I couldn't upgrade the package so I copied the solution from GitHub to my project and matched it to JS instead of TS.

devServer: {
    logLevel: 'debug',
    proxy: {
      '/myappapi/api/*': {
        target: 'http://foo.local.bar.com/',
        headers: {
          Cookie: ".MyCookie=12345"
        },
        logLevel: 'debug',
        secure: false,
        changeOrigin: true,
        withCredentials: true,
        onProxyReq: fixRequestBody, // Here is the solution!!!
      }
    },

And the function is -

const queryString = require('queryString');

function fixRequestBody(proxyReq,req){
  const requestBody = req?.body;
  if (!requestBody || !Object.keys(requestBody).length) {
    return;
  }

  const contentType = proxyReq.getHeader('Content-Type');
  const writeBody = (bodyData) => {
    // deepcode ignore ContentLengthInCode: bodyParser fix
    proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
    proxyReq.write(bodyData);
  };

  if (contentType && contentType.includes('application/json')) {
    writeBody(JSON.stringify(requestBody));
  }

  if (contentType === 'application/x-www-form-urlencoded') {
    writeBody(queryString.stringify(requestBody));
  }
}
  • Related