stegano / next-http-proxy-middleware

HTTP Proxy middleware available in API Middleware provided by Next.js.
231 stars 19 forks source link

How to pass self response data with selfHandleResponse in NextJS #80

Closed phatify closed 1 year ago

phatify commented 1 year ago

I want to handle the self response data (I want to do something like set a some data to cookie, etc...) in Next.js API Routes, but if I set it to true, none of the webOutgoing passes are called, that resulted in my request never being responded. What should I do?

    const handleProxyInit = (proxy) => {
        proxy.on('proxyRes', (proxyRes, req, res) => {
            let body = [];

            proxyRes.on('data', function (chunk) {
                body.push(chunk);
            });
            proxyRes.on('end', function () {
                body = Buffer.concat(body).toString('utf8');
                // do something here
            });
        });
    };

    httpProxyMiddleware(req, res, {
        ...,
        selfHandleResponse: true,
        changeOrigin: true,
        onProxyInit: handleProxyInit,
    });
stegano commented 1 year ago

Hi @phatify

Try this

    const handleProxyInit = (proxy) => {
        proxy.on('proxyRes', (proxyRes, req, res) => {
            let body = [];

            proxyRes.on('data', function (chunk) {
                body.push(chunk);
            });
            proxyRes.on('end', function () {
                body = Buffer.concat(body).toString('utf8');
                // do something here
                res.end(body); // <- Added
            });
        });
    };

    httpProxyMiddleware(req, res, {
        ...,
        selfHandleResponse: true,
        changeOrigin: true,
        onProxyInit: handleProxyInit,
    });

If you enable the selfHandleResponse flag provided by http-proxy, it seems that the end event handler handled internally by next-http-proxy-middleware is ignored.

So you need to call the res.end function directly or disable the selfHandleResponse flag.

phatify commented 1 year ago

Hi @phatify

Try this

    const handleProxyInit = (proxy) => {
        proxy.on('proxyRes', (proxyRes, req, res) => {
            let body = [];

            proxyRes.on('data', function (chunk) {
                body.push(chunk);
            });
            proxyRes.on('end', function () {
                body = Buffer.concat(body).toString('utf8');
                // do something here
                res.end(body); // <- Added
            });
        });
    };

    httpProxyMiddleware(req, res, {
        ...,
        selfHandleResponse: true,
        changeOrigin: true,
        onProxyInit: handleProxyInit,
    });

If you enable the selfHandleResponse flag provided by http-proxy, it seems that the end event handler handled internally by next-http-proxy-middleware is ignored.

So you need to call the res.end function directly or disable the selfHandleResponse flag.

@stegano Thank you so much! I am tried but unfortunately I am getting a junked body below:

image

stegano commented 1 year ago

🤔 Can you see the response headers? I think you are missing encoding information in the response header.

phatify commented 1 year ago

🤔 Can you see the response headers? I think you are missing encoding information in the response header.

@stegano Here is my response headers see in browser:

image

And the axios config for calling:

const axiosInstance = axios.create({
    baseURL: 'http://localhost:3001/api',
    headers: {
        'Content-Type': 'application/json',
    },
    timeout: 10000, 
    withCredentials: true,
});

axiosInstance.interceptors.request.use(
    (request) => {
        return request;
    },
    (error) => {
        return Promise.reject(error);
    },
);

axiosInstance.interceptors.response.use(
    (response) => {
        return response.data;
    },
    (error) => {
        return Promise.reject(error);
    },
);
phatify commented 1 year ago

Please forgive me, I don't know what I'm missing, this is my first time working with Buffer data :)

stegano commented 1 year ago

@phatify Can I see your handleProxyInit code? When converting a buffer to a string, you can specify the encoding type as an argument as shown below.

buffer.toString('utf-8');
phatify commented 1 year ago

@phatify Can I see your handleProxyInit code? When converting a buffer to a string, you can specify the encoding type as an argument as shown below.

buffer.toString('utf-8');

@stegano You can see my handleProxyInit:

image

phatify commented 1 year ago

@stegano I tried to get decoding response data by console.log(body) in handleProxyInitand see the result was as I expected. But when it sending to client, this response data still encoding, you can see in this comment: https://github.com/stegano/next-http-proxy-middleware/issues/80#issuecomment-1365657403. my response data from client can't get the expected result

stegano commented 1 year ago

Try setting Content-Type response header. Can i see your expected data?

    const handleProxyInit = (proxy) => {
        proxy.on('proxyRes', (proxyRes, req, res) => {
            let body = [];

            proxyRes.on('data', function (chunk) {
                body.push(chunk);
            });

            proxyRes.on('end', function () {
                body = Buffer.concat(body).toString('utf8');
                res.setHeader('content-type', 'text/html; charset=utf-8'); // <- Add or origin response `content-type` header
                res.end(body);
            });
        });
    };

   ...
phatify commented 1 year ago

@stegano , of course, my data received below: image

image

phatify commented 1 year ago

It seems I have no other way, I would disable the selfHandleResponse flag

stegano commented 1 year ago

It seems I have no other way, I would disable the selfHandleResponse flag

@phatify Hmm.. Finally, try removing the accept-encoding from the request header I think... the original data is compressed or incorrectly encoded.

stegano commented 1 year ago

@stegano I tried to get decoding response data by console.log(body) in handleProxyInitand see the result was as I expected. But when it sending to client, this response data still encoding, you can see in this comment: #80 (comment). my response data from client can't get the expected result

Does this mean that you could see non-crashed data? I tried to get decoding response data by console.log(body) in handleProxyInit and see the result was as I expected.