从 MongoDB 下载文件时在 Chrome 中获取 "Failed - File incomplete"
Getting "Failed - File incomplete" in Chrome when downloading file from MongoDB
我的 JavaScript 应用程序允许用户下载文件。该页面显示文件的可点击 link。该文件存储在 MongoDB 中。当我单击 link 下载文件时,我在 Chrome 中收到“失败 - 文件不完整”。文件下载应该显示在我的下载文件中,但它没有。我不知道出了什么问题,我希望这里的人能对这个问题有所了解。
此应用是使用 node/express/ejs/MongoDB
构建的
这是路由器代码:
router.get('/:id/download', async (req, res) => {
try {
const bug = await Bug.findById(req.params.id)
let buf = Buffer.from(bug.files)
res.writeHead(200, {
'Content-Disposition': `attachment; filename="${bug.fileName}"`,
'Content-Type': bug.fileType,
'Content-Length': buf.length,
}).end()
fs.writeFile(bug.fileName, buf, (err) => {
if (err) {
console.log(err);
}
else {
console.log("File written successfully\n");
}
})
} catch (err) {
console.log("error downloading file", err)
}
res.end()
})
这是 HTML:
<div class="container-sm mt-5">
<div class="row">
<div class="col-lg-3"></div>
<div class="col-lg-6">
<h2>Bug Details</h2>
<p>Title: <%= bug.title %></p>
<p>Description: <%= bug.description %></p>
<p>Category: <%= bug.category %></p>
<p>Status: <%= bug.status %></p>
<p>Priority: <%= bug.priority %></p>
<p>Supporting Documents: </p>
<a href="/<%= bug.id %>/download"><%= bug.fileName %></a>
<div>
<a href="/<%= bug.id %>/edit">Edit</a>
<form class="mt-3" method="POST" action="/<%= bug.id %>?_method=DELETE">
<button type="submit">Delete</button>
</form>
</div>
</div>
<div class="col-lg-3"></div>
</div>
</div>
在 MongoDB 中,文件存储为文档的一部分:
files: {
type: Buffer,
required: false
},
fileName: {
type: String,
required: false
},
fileType: {
type: String,
required: false
},
fileSize: {
type: Number,
required: false
}
当我使用虚拟 .txt 文件进行测试时,Chrome 开发工具将响应 header 显示为:
HTTP/1.1 200 OK X-Powered-By: Express Content-Disposition: attachment;
filename="dummyfile.txt" Content-Type: text/plain Content-Length: 9
Date: Fri, 06 May 2022 20:19:01 GMT Connection: keep-alive Keep-Alive:
timeout=5
一个有趣的旁注:该文件确实下载到我的项目文件夹中并且一切正常,但它没有按应有的方式下载到我的 /downloads 文件夹中。
你应该使用express提供的res.download
方法,不需要设置任何headers。
此外,我正在使用 fs promises 模块来实现异步等待语法
const fs = require("fs").promises;
router.get("/:id/download", async (req, res) => {
try {
const bug = await Bug.findById(req.params.id);
let buf = Buffer.from(bug.files);
await fs.writeFile(bug.fileName,buf);
res.download(bug.fileName, err => {
if (err) {
throw err;
} else {
// If download is complete
if (res.headersSent) {
// if you want to delete the file which was created locally after download is complete
fs.rm(bug.fileName);
}
}
});
} catch (err) {
console.log("error downloading file", err);
}
});
我的 JavaScript 应用程序允许用户下载文件。该页面显示文件的可点击 link。该文件存储在 MongoDB 中。当我单击 link 下载文件时,我在 Chrome 中收到“失败 - 文件不完整”。文件下载应该显示在我的下载文件中,但它没有。我不知道出了什么问题,我希望这里的人能对这个问题有所了解。
此应用是使用 node/express/ejs/MongoDB
构建的这是路由器代码:
router.get('/:id/download', async (req, res) => {
try {
const bug = await Bug.findById(req.params.id)
let buf = Buffer.from(bug.files)
res.writeHead(200, {
'Content-Disposition': `attachment; filename="${bug.fileName}"`,
'Content-Type': bug.fileType,
'Content-Length': buf.length,
}).end()
fs.writeFile(bug.fileName, buf, (err) => {
if (err) {
console.log(err);
}
else {
console.log("File written successfully\n");
}
})
} catch (err) {
console.log("error downloading file", err)
}
res.end()
})
这是 HTML:
<div class="container-sm mt-5">
<div class="row">
<div class="col-lg-3"></div>
<div class="col-lg-6">
<h2>Bug Details</h2>
<p>Title: <%= bug.title %></p>
<p>Description: <%= bug.description %></p>
<p>Category: <%= bug.category %></p>
<p>Status: <%= bug.status %></p>
<p>Priority: <%= bug.priority %></p>
<p>Supporting Documents: </p>
<a href="/<%= bug.id %>/download"><%= bug.fileName %></a>
<div>
<a href="/<%= bug.id %>/edit">Edit</a>
<form class="mt-3" method="POST" action="/<%= bug.id %>?_method=DELETE">
<button type="submit">Delete</button>
</form>
</div>
</div>
<div class="col-lg-3"></div>
</div>
</div>
在 MongoDB 中,文件存储为文档的一部分:
files: {
type: Buffer,
required: false
},
fileName: {
type: String,
required: false
},
fileType: {
type: String,
required: false
},
fileSize: {
type: Number,
required: false
}
当我使用虚拟 .txt 文件进行测试时,Chrome 开发工具将响应 header 显示为:
HTTP/1.1 200 OK X-Powered-By: Express Content-Disposition: attachment; filename="dummyfile.txt" Content-Type: text/plain Content-Length: 9 Date: Fri, 06 May 2022 20:19:01 GMT Connection: keep-alive Keep-Alive: timeout=5
一个有趣的旁注:该文件确实下载到我的项目文件夹中并且一切正常,但它没有按应有的方式下载到我的 /downloads 文件夹中。
你应该使用express提供的res.download
方法,不需要设置任何headers。
此外,我正在使用 fs promises 模块来实现异步等待语法
const fs = require("fs").promises;
router.get("/:id/download", async (req, res) => {
try {
const bug = await Bug.findById(req.params.id);
let buf = Buffer.from(bug.files);
await fs.writeFile(bug.fileName,buf);
res.download(bug.fileName, err => {
if (err) {
throw err;
} else {
// If download is complete
if (res.headersSent) {
// if you want to delete the file which was created locally after download is complete
fs.rm(bug.fileName);
}
}
});
} catch (err) {
console.log("error downloading file", err);
}
});