节点 REST API 图像渲染问题
Node REST API Image rendering issue
我在网页上显示简单图像时遇到问题。我有一个用于 API 的节点后端和一个用于视图页面的节点 Web 服务器。
代码运行良好,但我需要添加一种网关 in-between(将来会处理身份验证),它破坏了代码。
我正在使用 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, e.g. 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
- 类型:text/html
- 大小:未知(未缓存)
我做错了什么?非常感谢。
使用 Alexander 输入进行编辑
网关(节点)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);
});
});
后端APIV2
//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, e.g. 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);
}
结果还是不好:图片没有显示。但是现在,content-type 已正确设置。
在此处添加 headers(邮递员):
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
是的,我已经在为页面的所有其他组件使用控制器,但我直接从 html 页面调用 API 来检索图像。你说得对,我可以改变它。
网关在这里也是因为我有多个 API 组件(微服务架构),因此网关是为 Web 客户端抽象所有这些不同组件的好方法。
我更愿意让网关遵循微服务架构模式。
更新
尝试在请求中将 encoding
属性 设置为 null
object:
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);
});
});
此外,将图片 content-type headers 设置为您的回复:
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);
});
});
我在网页上显示简单图像时遇到问题。我有一个用于 API 的节点后端和一个用于视图页面的节点 Web 服务器。 代码运行良好,但我需要添加一种网关 in-between(将来会处理身份验证),它破坏了代码。
我正在使用 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, e.g. 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 - 类型:text/html - 大小:未知(未缓存)
我做错了什么?非常感谢。
使用 Alexander 输入进行编辑
网关(节点)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);
});
});
后端APIV2
//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, e.g. 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);
}
结果还是不好:图片没有显示。但是现在,content-type 已正确设置。
在此处添加 headers(邮递员):
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
是的,我已经在为页面的所有其他组件使用控制器,但我直接从 html 页面调用 API 来检索图像。你说得对,我可以改变它。 网关在这里也是因为我有多个 API 组件(微服务架构),因此网关是为 Web 客户端抽象所有这些不同组件的好方法。 我更愿意让网关遵循微服务架构模式。
更新
尝试在请求中将 encoding
属性 设置为 null
object:
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);
});
});
此外,将图片 content-type headers 设置为您的回复:
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);
});
});