节点REST API图像呈现问题

我有一个问题,在网页上显示一个简单的图像。 我有一个API的节点后端和查看页面的节点Web服务器。 代码工作得很好,但我需要添加一个中间网关(将在未来处理身份validation),它打破了代码。

我使用express和gridfs来存储并从mongo文件中取回。

这是代码

HTML / Angular页面

<img id="image" ng-src="http:localhost:3000/api/files/images/{{data.image}}" alt="" /> 

网关(节点)

 var request = require('request'); //settings - retrive the url of the api backend micro-service var url = require('./configApiGw').url_service_api_contents; //api to retrive a file stored in mongo using gridfs app.get('/api/files/images/:id', function(req, res, next){ var uri = url+'/api/files/images/:'+req.params.id; request({ uri: uri, method: "GET", timeout: 100000, followRedirect: true, maxRedirects: 10 }, function(error, response, body) { res.send(response.body); }); }); 

后端API

 app.get('/api/files/images/:id', function(req, res, next){ //call function to read the file using gridfs. call back function readFile(req, res, function(file){ console.log('success'); }); }); function readFile(req,res,callback){ var fileId = req.params.id; //delete the ':' that is added by the gateway if(fileId.charAt(0) === ':'){ fileId = fileId.slice(1); } // streaming from gridfs var rstream = gfs.createReadStream({filename: fileId}); var bufs = []; rstream.on('data', function (chunk) { bufs.push(chunk); }); // done reading the file rstream.on('end', function () { var fbuf = Buffer.concat(bufs); var file = (fbuf.toString('base64')); callback(file); }); //error handling, eg file does not exist rstream.on('error', function (err) { console.log('An error occurred!', err); console.log(err); res.send(500,err); }); rstream.pipe(res); } 

图像不显示,但我从API后端和网关得到200 OK响应。 当我查看浏览器上的图像细节时,我看到以下数据: – 位置: http:// localhost:3000 / api / files / images / file.jpeg – types:text / html – 大小:未知)

我究竟做错了什么? 非常感谢。

用Alexandrinput进行编辑

网关(节点)V2

 var request = require('request'); //settings - retrive the url of the api backend micro-service var url = require('./configApiGw').url_service_api_contents; app.get('/api/files/images/:id', function(req, res, next){ var uri = url+'/api/files/images/:'+req.params.id; request({ uri: uri, method: "GET", timeout: 100000, followRedirect: true, maxRedirects: 10 }, function(error, response, body) { res.set('Content-Type', response.headers['content-type']); res.send(response.body); }); }); 

后端API V2

 //api to retrive a file stored in mongo using gridfs app.get('/api/files/images/:id', function(req, res, next){ //call function to read the file using gridfs. call back function db.readFile(req, res, function(file){ //res.send(file); console.log("success"); }); }); readFile = function(req,res,callback){ var fileId = req.params.id; //delete the ':' that is added by the gateway if(fileId.charAt(0) === ':'){ fileId = fileId.slice(1); } //setHeaders content type for the file setHeaders(fileId, function(contentType){ res.writeHead('200',{'Content-Type':contentType}); // streaming from gridfs var rstream = gfs.createReadStream({filename: fileId}); var bufs = []; rstream.on('data', function (chunk) { bufs.push(chunk); }); // done reading the file rstream.on('end', function () { var fbuf = Buffer.concat(bufs); var file = (fbuf.toString('binary')); callback(file); }); //error handling, eg file does not exist rstream.on('error', function (err) { console.log('An error occurred!', err); console.log(err); res.send(500,err); }); rstream.pipe(res); }); }; function setHeaders(fileId, callback){ var ext = path.extname(fileId); var contentType = 'text/html'; if (ext === '.gif') { contentType = 'image/gif'; } if (ext === '.jpeg') { contentType = 'image/jepg'; } if (ext === '.png') { contentType = 'image/png'; } if (ext === '.jpg') { contentType = 'image/jpg'; } callback(contentType); } 

结果仍然不好:图像不显示。 但现在,内容types正确设置。

在这里添加标题(邮差):

 Access-Control-Allow-Headers → Origin, X-Requested-With, Content-Type, Accept Access-Control-Allow-Origin → * Connection → keep-alive Content-Length → 82360 Content-Type → image/jepg; charset=utf-8 Date → Fri, 20 Nov 2015 10:15:55 GMT ETag → W/"141b8-Ox5qDdvc3kZTunf0uqMVQg" X-Powered-By → Express 

UPDATE

尝试在请求对象中将encoding属性设置为null

 app.get('/api/files/images/:id', function(req, res, next){ var uri = url+'/api/files/images/:'+req.params.id; request({ uri: uri, method: "GET", timeout: 100000, followRedirect: true, encoding: null, maxRedirects: 10 }, function(error, response, body) { res.set('Content-Type', response.headers['content-type']); res.send(response.body); }); }); 

另外,将图片内容types标题设置为您的回复:

 app.get('/api/files/images/:id', function(req, res, next){ //call function to read the file using gridfs. call back function readFile(req, res, function(file){ res.set('Content-Type', 'image/jpeg'); //it can different, depends on the image res.send(file); }); }); 

网关:

 app.get('/api/files/images/:id', function(req, res, next){ var uri = url+'/api/files/images/:'+req.params.id; request({ uri: uri, method: "GET", timeout: 100000, followRedirect: true, maxRedirects: 10 }, function(error, response, body) { res.set('Content-Type', response.headers['content-type']); res.send(response.body); }); }); 

是的,我已经使用一个控制器的页面的所有其他组件,但我直接从HTML页面调用API来检索图像。 你是对的,我可以改变这一点。 网关在这里也是因为我有多个API组件(微服务体系结构),所以网关是一个很好的方式来为Web客户端抽象所有这些不同的组件。 我宁愿保持网关遵循微服务架构模式。