尝试提供在Express Mifdredware现场下载的图像
我在Express和中间件方面很难。 基本上,我要做的是在磁盘上使用图像,但是如果它不存在,请从某些外部服务器下载它,然后使用/显示。然后,对图像的第二和以下请求将从磁盘上提供图像。
因此,下载不是问题,该问题是在下载后立即服务的。 使用下面的代码,将导致所有图像正在下载,并在浏览器中显示一些图像。但是它会下雨消息说:
错误:发送后无法设置标头。
tldr; 我有两个问题:
- 我会收到诸如:错误:发送后无法设置标头的消息。
- 尽管我所有的图像都将在浏览器中显示,尽管所有图像都已在磁盘上的正确位置下载。
额外信息:
这些图像来自\ public \ files
我正在使用custom server.js使用nextjs 我不确定是否需要在发送文件后结束响应。我知道服务器('*')给出错误:发送后无法设置标头。但是我不确定如何减轻这个问题,因为这样做了这样的事情:
server.all('*', (req, res) => {
if(!req.url.startsWith('/files')){
return handle(req, res)
}
})
使事情变得更糟,并且会使图像消失已经下载并以前工作了。因此,比我认为我需要始终做sendfile,但是我似乎无法等待捕获中的下载,并且会吐出错误的错误: 错误:Enoent:没有这样的文件或目录,
我将与大家分享中间件:
var download = async function (from, to, callback) {
await createDirectory(to);
let fileStream = fsclassic.createWriteStream(to);
request(from).pipe(fileStream).on('close', callback);
};
app.prepare().then(() => {
const server = express()
server.use('/files', async (req, res, next_middleware) => {
var file = path.join(__dirname, "public\\files", req.url);
try{
await fs.access(file, fsclassic.constants.F_OK);
}catch(e) {
await download(internalToExternal(req.url), file, () => {
res.status(200).sendFile(file);
});
}
next_middleware();
})
server.all('*', (req, res) => {
return handle(req, res)
})
server.listen(port, (err) => {
if (err) throw err
console.log(`> Ready on http://localhost:${port}`)
})
})
感谢您任何帮助!
I'm having a hard time with express and middleware.
Basically what I'm trying to do is serve an image on disk but if it does not exists, download it from some external server, and then serve/display it. The second and following requests to the image will then serve the image from disk.
So downloading is not the issue, the issue is serving the image right after it's been downloaded.
Using the code below, will result in all images being downloaded and some images shown in the browser. But it will rain messages saying:
Error: Can't set headers after they are sent.
TLDR;
I'm having two issues:
- I get messages like:Error: Can't set headers after they are sent.
- Not all my images will be shown in the browser, although all images have been downloaded in the correct location on disk.
extra info:
the images are served from \public\files
I'm using NextJS with a custom server.js
I'm not sure if I need to end the response after the sendFile. I know the server.all('*') gives the Error: Can't set headers after they are sent. But I'm not sure how to mitigate that problem since doing something like this:
server.all('*', (req, res) => {
if(!req.url.startsWith('/files')){
return handle(req, res)
}
})
made things worse, and would make images disappear that had already been downloaded, and worked before. So than I got to think that I need to ALWAYS do sendFile, but then I seemed not to be able to await the download in the catch and would spit out errors like:
Error: ENOENT: no such file or directory
I'll share the middleware with you guys:
var download = async function (from, to, callback) {
await createDirectory(to);
let fileStream = fsclassic.createWriteStream(to);
request(from).pipe(fileStream).on('close', callback);
};
app.prepare().then(() => {
const server = express()
server.use('/files', async (req, res, next_middleware) => {
var file = path.join(__dirname, "public\\files", req.url);
try{
await fs.access(file, fsclassic.constants.F_OK);
}catch(e) {
await download(internalToExternal(req.url), file, () => {
res.status(200).sendFile(file);
});
}
next_middleware();
})
server.all('*', (req, res) => {
return handle(req, res)
})
server.listen(port, (err) => {
if (err) throw err
console.log(`> Ready on http://localhost:${port}`)
})
})
I would appreciate any help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
所以我对自己的问题有一个答案。
我已经更改了文件的处理。AccessCall以不使用try:catch。
当文件存在时,我调用next_middleware(),该文件将在下载文件时将其处理到server.all('*')
时,我也会执行相同的操作,这也将处理control。 ')
这将导致图像在下载时以及重新访问网站时显示。
代码:
So I've got an answer to my own question.
I've changed the handling of the file.access call to not use try: catch.
when the file exists I call next_middleware() which will handle over control to the server.all('*')
when the file has been downloaded, I do the same, which will also handle control over to the server.all('*')
this will result in images being displayed when they have been downloaded, and when revisiting the site.
code: