【发布时间】:2020-04-23 04:34:56
【问题描述】:
我正在制作一个用于在地图上绘制运行路线并将其保存到 mongodb 数据库的应用程序。
目前,我正在使用 puppeteer 访问我的应用程序中的路线,并将坐标作为查询字符串传递给地图组件。加载地图后,我截取屏幕截图,将返回的 Buffer 转换为 base64 编码的字符串,将其保存到数据库中,并使用该字符串在前端显示图像。
整个过程的中间件是这样的:
exports.screenshotMap = async (req, res, next) => {
try {
const { lineFeatures } = req.body;
const browser = await puppeteer.launch({
args: ['--no-sandbox', '--disable-setuid-sandbox'],
});
// open new browser
const page = await browser.newPage();
// create array of coordinates from geojson features
const coords = lineFeatures.map(line => line.geometry.coordinates);
// reduce to 2D array of [lat, lon] coords
const flattenedCoords = coords.reduce((accum, arr) => {
return accum.concat(arr);
}, []);
// Stringify coords before using them as query string
const coordsStr = JSON.stringify(flattenedCoords);
// goto page with map sending coordintaes along
await page.goto(`http://localhost:3000/test?coords=${coordsStr}`, {
waitUntil: 'networkidle0',
});
// wait for map to load, call onLoad callback, and set state to make the h1 visible
await page.waitForSelector('h1');
// wait one more second to make sure all tiles for the map are loaded. Longer routes can require significantly more tiles
await page.waitFor(1000);
const image = await page.screenshot({
type: 'jpeg',
quality: 100,
clip: {
x: 0,
y: 70,
width: 640,
height: 360,
},
omitBackground: true,
});
await browser.close();
// convert buffer to base64 string
const base64Image = await image.toString('base64');
// attach to request object to be used in the next middleware
req.image = base64Image;
next();
} catch (err) {
res.status(400).send(err);
}
};
这种方法有效,但是我想知道是否有更好的方法。我已经阅读了存储 Buffer 数据对于数据库内存目的来说更好,因为 base64 字符串很长。更好的方法是保存缓冲区数据并将其转换为编码字符串,然后再将其发送回客户端?有没有推荐的方法来处理这种数据?我有兴趣听听其他人的想法和方法。
【问题讨论】:
-
我最终将图像保存到 S3 存储桶中。 page.screenShot 返回一个缓冲区,您可以使用该缓冲区将图像保存到 S3。然后将返回的唯一 url 保存到您选择的数据库中。