我正在尝试制作上传和下载PDF文件的应用程序。正如标题中提到的,我使用MongoDB和Next.js。我的文件将小于16 MB,所以我可以将它们作为一个完整的二进制文件存储。上传似乎工作正常,但我不确定(数据库中有文件内容,似乎很奇怪,是PDF文件)。但下载返回PDF,无法打开/加载或为空。
上传:客户端
const uploadHandler = async (e, fileName) => {
const Tempfile = e.target.files[0]
if (!Tempfile) {
return
}
// check file size
const size = parseInt(((Tempfile.size/1024)/1024).toFixed(4))
if (size > 16) {
popupHandler("File too large!")
}
// rename file from https://stackoverflow.com/questions/21720390/how-to-change-name-of-file-in-javascript-from-input-file
let file = new File([Tempfile.slice(0, Tempfile.size, 'application/pdf')], `${fileName}.pdf`, {type: 'application/pdf'});
// create formData
const form = new FormData();
form.append('myFile', file)
// upload
const response = await fetch('/api/upload', {
method: 'POST',
body: form
})
if (response.status === 200) {
console.log('succ')
}
}
服务器(Next.js API):
import { NextApiRequest, NextApiResponse } from "next/types";
import { connectToDatabase } from "../../../../database/database";
import { IncomingForm } from 'formidable'
import { promises as fs } from 'fs'
// https://stackoverflow.com/questions/60465564/create-upload-files-api-in-next-js
export const config = {
api: {
bodyParser: false,
}
};
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== 'POST') {
return res.status(400).json({message: 'Bad request'});
}
const client = await connectToDatabase();
const database = client.db("Test").collection("Files");
try {
const data: any = await new Promise((resolve, reject) => {
const form = new IncomingForm()
form.parse(req, async (err, fields, files) => {
if (err) return reject(err)
resolve({ fields, files })
})
})
const contents = await fs.readFile(data?.files?.myFile.filepath, {
encoding: 'utf8',
})
const FILE = {
"fileName": data?.files?.myFile.originalFilename,
"content": contents
}
await database.insertOne(FILE)
} catch(e) {
console.error(e)
client.close();
return res.status(400).json({message: "Uploading failed!"});
}
client.close();
return res.status(200).json({ message: 'succ!' })
}
下载:
委托单位:
const downloadHandler = async (fileName) => {
const response = await fetch('/api/download', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({fileName})
})
if (response.status !== 200) {
return
} else {
// https://stackoverflow.com/questions/68490546/how-to-download-a-file-on-next-js-using-an-api-route
const data = await response.blob()
const url = window.URL.createObjectURL(data)
const a = document.createElement('a')
a.style.display = 'none'
a.href = url
a.setAttribute('download', `${fileName}.pdf`)
document.body.appendChild(a)
a.click()
window.URL.revokeObjectURL(url)
document.body.removeChild(a)
}
}
伺服器:
import { NextApiRequest, NextApiResponse } from "next/types";
import { connectToDatabase } from "../../../../database/database";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== 'POST') {
return res.status(400).json({message: 'Bad request'});
}
const { fileName } = req.body
const client = await connectToDatabase();
const database = client.db("Test").collection("Files");
const result = await database.findOne({ fileName: `${fileName}.pdf` }, { projection: {_id: 0} } );
if (!result) {
client.close();
return res.status(400).json({message: "File not found!"});
}
client.close();
return res.status(200).setHeader('Content-Type', 'application/pdf').setHeader("Content-Disposition", "attachment; filename=" + result.fileName).send(result.content);
}
您能向我解释一下为什么我无法打开这些PDF文件或之后看不到它们的内容吗?提前感谢
1条答案
按热度按时间avwztpqn1#
最后我调试了一下,下面是给我的程序员同事的结果代码:
客户端上传:
然后服务器上传:
下载客户端
和服务器下载:
正如在KJ的评论中提到的,问题是编码-所以现在是pdf存储在base64和发送回和第四