在 Meteor 中显示私有子目录中的图像
Displaying images from private subdirectory in Meteor
我有一组图像存储在我的 /private
子目录中,我试图在服务器方法中检索数据并将数据发送回客户端以进行显示。
我该怎么做?
我在 /private/photos
中有一个名为 test.png
的图像。这是我试过的。
/client/test.js
Template.test.onRendered(function () {
Meteor.call('returnPhoto', 'photos/test.png', function (e, data) {
console.log(data);
console.log(window.btoa(data));
$('#imgContainerImg').attr('src', 'data:image/png;base64,' + window.btoa(data));
});
})
/server/methods.js
returnPhoto: function (assetPath) {
return Assets.getText(assetPath);
return Assets.getBinary(assetPath);
}
我都试过了 Assets.getText
and Assets.getBinary
,第一个给了我一些二进制乱码,第二个给了我一个数字数组。使用 btoa
函数无论如何都不起作用。
我看过CollectionFS package, but I do not need to upload the pictures and store them all in a collection. I'd like the images to be available as soon as I put them in that directory, without having to call myFSCollection.insert
。
使用以下方法,我能够从私有目录中获取图像,将其作为字节数组发送到客户端,然后将其转换为 base64 字符串并显示为数据 URL。
client/test.js
Template.test.onRendered(function () {
Meteor.call('returnPhoto', 'photos/test.png', function (e, data) {
var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(data)));
$('#imgContainerImg').attr('src', 'data:image/png;base64,' + base64String);
});
})
server/methods.js
returnPhoto: function (assetPath) {
return Assets.getBinary(assetPath);
}
这是我使用的解决方案:
client/main.js
const imagesLookup = new ReactiveDict();
Template.registerHelper('img', function(src) {
Meteor.call('image', src, (err, img)=> {
imagesLookup.set(src, img);
});
return imagesLookup.get(src);
});
client/main.html
<template="stuffWithImage">
<!-- src is the path of the image in private -->
<img src="{{img src}}"/>
</template>
imports/methods.js
Meteor.methods({
image(src){
//validate input and check if use is allowed to see this asset
if(Meteor.isClient){
//return some loading animation
}
const buffer = new Buffer(Assets.getBinary(src), 'binary');
const magicNumber = buffer.toString('hex',0,4)
const base64String = buffer.toString('base64');
return `data:image/${getImageType(magicNumber)};base64,${base64String}`;
}
});
function getImageType(magicNumber){
if (magicNumber === 'ffd8ffe0') {
return 'jpeg';
}
//check for other formats... here is a table: https://asecuritysite.com/forensics/magic
}
我有一组图像存储在我的 /private
子目录中,我试图在服务器方法中检索数据并将数据发送回客户端以进行显示。
我该怎么做?
我在 /private/photos
中有一个名为 test.png
的图像。这是我试过的。
/client/test.js
Template.test.onRendered(function () {
Meteor.call('returnPhoto', 'photos/test.png', function (e, data) {
console.log(data);
console.log(window.btoa(data));
$('#imgContainerImg').attr('src', 'data:image/png;base64,' + window.btoa(data));
});
})
/server/methods.js
returnPhoto: function (assetPath) {
return Assets.getText(assetPath);
return Assets.getBinary(assetPath);
}
我都试过了 Assets.getText
and Assets.getBinary
,第一个给了我一些二进制乱码,第二个给了我一个数字数组。使用 btoa
函数无论如何都不起作用。
我看过CollectionFS package, but I do not need to upload the pictures and store them all in a collection. I'd like the images to be available as soon as I put them in that directory, without having to call myFSCollection.insert
。
使用以下方法,我能够从私有目录中获取图像,将其作为字节数组发送到客户端,然后将其转换为 base64 字符串并显示为数据 URL。
client/test.js
Template.test.onRendered(function () {
Meteor.call('returnPhoto', 'photos/test.png', function (e, data) {
var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(data)));
$('#imgContainerImg').attr('src', 'data:image/png;base64,' + base64String);
});
})
server/methods.js
returnPhoto: function (assetPath) {
return Assets.getBinary(assetPath);
}
这是我使用的解决方案:
client/main.js
const imagesLookup = new ReactiveDict();
Template.registerHelper('img', function(src) {
Meteor.call('image', src, (err, img)=> {
imagesLookup.set(src, img);
});
return imagesLookup.get(src);
});
client/main.html
<template="stuffWithImage">
<!-- src is the path of the image in private -->
<img src="{{img src}}"/>
</template>
imports/methods.js
Meteor.methods({
image(src){
//validate input and check if use is allowed to see this asset
if(Meteor.isClient){
//return some loading animation
}
const buffer = new Buffer(Assets.getBinary(src), 'binary');
const magicNumber = buffer.toString('hex',0,4)
const base64String = buffer.toString('base64');
return `data:image/${getImageType(magicNumber)};base64,${base64String}`;
}
});
function getImageType(magicNumber){
if (magicNumber === 'ffd8ffe0') {
return 'jpeg';
}
//check for other formats... here is a table: https://asecuritysite.com/forensics/magic
}