Reputation: 659
I am trying to pipe an image response from an internal API, using NodeJS Express to an external endpoint. I.e. proxying an image.
This is what I have tried, but I keep getting an empty box instead of the image:
app.get('/image', (req, res) => {
res.setHeader('Content-Type', 'image/png');
request.get(`http://localhost:8080/image`).pipe(res);
// Also tried reading from a file and not the endpoint
//to make sure it's not a problem with "request" library with same results
//fs.createReadStream('./image.png').pipe(res);
});
Using browser dev tools I can also see that the size of the empty image I get on the external endpoint is bigger then that of the working image got from the internal endpoint.
Accessing the endpoint from "Postman" seems to give the image without problems, but accessing from Firefox says that the image has errors.
So it seems to be some kind of an encoding issue which I can't seem to figure out how to fix. Please help.
Upvotes: 0
Views: 1780
Reputation: 659
Thank you slideshowp2 for taking your time and pointing out that, my provided code should indeed work.
It would have been impossible to figure out the issue with the info that I gave.
I was using "livereload" middleware in my project.
This middleware intersects all the responses coming from my server and tries to inject the liverelad script into them.
By default it is configured to ignore responses for endpoints ending with ".png" and other image and binary formats.
Adding ".png" to the endpoint path, solved the issue.
app.get('/image.png', (req, res) => {
request.get(`http://localhost:8080/image`).pipe(res);
});
Upvotes: 0
Reputation: 102527
Can't reproduce your issue. The below example works fine. Testing environment:
E.g.
server-internal.ts
:
import express from 'express';
import fs from 'fs';
import path from 'path';
const app = express();
const port = 8080;
app.get('/image', (req, res) => {
console.log('internal server /image');
res.setHeader('Content-Type', 'image/png');
fs.createReadStream(path.resolve(__dirname, './image.png')).pipe(res);
});
app.listen(port, () => console.log('HTTP server is listening on port:', port));
server-external.ts
:
import express from 'express';
import request from 'request';
const app = express();
const port = 3000;
app.get('/image', (req, res) => {
console.log('external server /image');
res.setHeader('Content-Type', 'image/png');
request.get(`http://localhost:8080/image`).pipe(res);
});
app.listen(port, () => console.log('HTTP server is listening on port:', port));
Access http://localhost:3000/image
, got the image correctly.
The logs of the internal server:
HTTP server is listening on port: 8080
internal server /image
The logs of the external server:
HTTP server is listening on port: 3000
external server /image
source code: https://github.com/mrdulin/expressjs-research/tree/master/src/stackoverflow/64302729
Upvotes: 1