【发布时间】:2022-10-18 18:39:44
【问题描述】:
我想在我的 NextJS 应用程序中显示 Google Place Photos。要从它们指定的 URL 获取这些图像,需要一个 API 密钥,但同时,我不想将此 API 密钥公开给公众。
我的目标是实现一个 NextJS API 路由,该路由从 Google Places Photos 中获取并返回指定的图像,同时也能够直接从图像标签中访问,如下所示:
<img src={`/api/photos/${place?.photos[0].photo_reference}`} alt='' />
我在网上找到了一些不同的来源,建议我将 google 请求中的响应流直接传输到传出响应的响应流,如下所示:
export default async function handler(
req: NextApiRequest,
res: NextApiResponse,
) {
const response = await fetch(
`https://maps.googleapis.com/maps/api/place/photo
&photo_reference=${id}
&key=${process.env.GOOGLE_PLACE_API_KEY}`,
);
if (!response.ok) {
console.log(response);
res.status(500).end();
return;
}
response.body.pipe(res);
}
但是由于 response.body 是 ReadableStream,它没有 .pipe() 函数。相反,它有 .pipeTo() 和 .pipeThrough()。
然后我尝试了
response.body.pipeTo(res);
但是,这也不起作用,因为 res 是 NextApiResponse 而不是 WritableStream。虽然我在网上搜索过,但我还没有找到类似于 WritableStreams 的写入 NextApiResponse 的方法。
最后,我尝试手动将响应转换为缓冲区并将其写入 NextApiResponse,如下所示:
export default async function handler(
req: NextApiRequest,
res: NextApiResponse,
) {
const response = await fetch(
`https://maps.googleapis.com/maps/api/place/photo
&photo_reference=${id}
&key=${process.env.GOOGLE_PLACE_API_KEY}`,
);
if (!response.ok) {
console.log(response);
res.status(500).end();
return;
}
const resBlob = await response.blob();
const resBufferArray = await resBlob.arrayBuffer();
const resBuffer = Buffer.from(resBufferArray);
const fileType = await fileTypeFromBuffer(resBuffer);
res.setHeader('Content-Type', fileType?.mime ?? 'application/octet-stream');
res.setHeader('Content-Length', resBuffer.length);
res.write(resBuffer, 'binary');
res.end();
}
虽然这完成了响应,但没有显示任何图像。
如何将检索到的谷歌地点图像从服务器直接传递到前端,以便标签可以使用它?
【问题讨论】:
标签: javascript node.js google-maps-api-3 next.js node-fetch