Compare commits

...

5 Commits

Author SHA1 Message Date
503fae7cc7 实现了文件下载时界面及密码的输入 2022-08-26 20:29:00 +08:00
4006decb81 新建download.pug 2022-08-26 20:28:03 +08:00
9854bfeed6 清空 2022-08-26 20:27:22 +08:00
e757feed04 小修改 2022-08-26 20:26:21 +08:00
a1bff06a26 重命名 2022-08-26 20:26:06 +08:00
5 changed files with 56 additions and 22 deletions

View File

@ -1 +1 @@
file_input.value = null // file_input.value = null

View File

@ -10,6 +10,7 @@ body {
margin: 0 auto; margin: 0 auto;
} }
p,
h1, h1,
form { form {
margin: 1rem auto; margin: 1rem auto;

View File

@ -20,7 +20,7 @@ app.use(express.static('public'))
app.use(express.urlencoded({ extended: true })) app.use(express.urlencoded({ extended: true }))
app.use(express.json()) app.use(express.json())
app.get('/', (req, res) => { app.get('/', (req, res) => {
res.render('index') res.render('upload')
}) })
const upload = multer({ dest: TEMP_PATH, limits: { fileSize: UPLOAD_SIZE_LIMIT } }) const upload = multer({ dest: TEMP_PATH, limits: { fileSize: UPLOAD_SIZE_LIMIT } })
app.post('/upload', upload.single('file'), async (req, res) => { app.post('/upload', upload.single('file'), async (req, res) => {
@ -31,27 +31,35 @@ app.post('/upload', upload.single('file'), async (req, res) => {
fs.cpSync(file_temp_path, file_save_path) // 复制文件到UPLOAD_PATH fs.cpSync(file_temp_path, file_save_path) // 复制文件到UPLOAD_PATH
} }
fs.unlinkSync(file_temp_path) // 删除临时文件 fs.unlinkSync(file_temp_path) // 删除临时文件
const file = { let file = {
md5, md5,
size: req.file.size, size: req.file.size,
encoding: req.file.encoding, encoding: req.file.encoding,
mimetype: req.file.mimetype, mimetype: req.file.mimetype,
filename: req.file.originalname, // 解决了multer将中文文件名错误编码的问题
filename: Buffer.from(req.file.originalname, 'latin1').toString('utf8'),
password: req.body.password ? await bcrypt.hash(req.body.password, 16) : '', password: req.body.password ? await bcrypt.hash(req.body.password, 16) : '',
} }
// 写入数据库 // 写入数据库
console.log(req.file)
console.log(file)
const fileshare = new Fileshare(file) const fileshare = new Fileshare(file)
file.id = (await fileshare.save()).id file = await fileshare.save()
console.table(file) console.log(file)
res.status(201).render('index', { file }) res.status(201).render('upload', { file })
}) })
app.get('/file/:id', async (req, res) => { app.get('/file/:id', async (req, res) => {
const file = await Fileshare.findByIdAndUpdate(req.params.id, { $inc: { downloads: 1 } }) const file = await Fileshare.findById(req.params.id)
res.render('download', { file })
})
app.post('/file/:id', async (req, res) => {
const file = await Fileshare.findById(req.params.id)
if (file) { if (file) {
const file_path = path.join(SAVE_PATH, file.md5) if (file.password == '' || (await bcrypt.compare(req.body.password, file.password)) == true) {
if (file.password == '') { await file.update({ $inc: { downloads: 1 } })
res.status(200).download(file_path, file.filename) res.status(200).download(path.join(SAVE_PATH, file.md5), file.filename)
} else { } else {
res.sendStatus(401)
} }
} else { } else {
res.sendStatus(404) res.sendStatus(404)

27
views/download.pug Normal file
View File

@ -0,0 +1,27 @@
doctype html
html(lang='zh')
head
meta(charset='UTF-8')
meta(http-equiv='X-UA-Compatible' content='IE=edge')
meta(name='viewport' content='width=device-width, initial-scale=1.0')
link(rel='icon' href='/favicon.ico' type='image/x-icon')
link(rel='stylesheet' href='/style.css')
title 下载文件
body
h1 下载文件
form(method='POST')
label 文件
label= file.filename
label 大小
label= file.size
|   字节
label 类型
label= file.mimetype
label 下载
label= file.downloads
|   次
if file.password
label(for='password_input') 密码
input(id='password_input' name='password' type='password' autocomplete='off' required)
button(id='download_button' type='submit') 下载
script(src='/client.js')

View File

@ -6,20 +6,18 @@ html(lang='zh')
meta(name='viewport' content='width=device-width, initial-scale=1.0') meta(name='viewport' content='width=device-width, initial-scale=1.0')
link(rel='icon' href='/favicon.ico' type='image/x-icon') link(rel='icon' href='/favicon.ico' type='image/x-icon')
link(rel='stylesheet' href='/style.css') link(rel='stylesheet' href='/style.css')
title 文件分享服务器 title 分享文件
body body
h1 文件分享服务器 h1 分享文件
if file if file
section section
h2 上传成功 p
ul | 文件  
li id #{file.id} var #{file.filename}  
li md5 #{file.md5} | 分享成功!
li size #{file.size} bytes p 链接  
li encoding #{file.encoding} -const url = '/file/' + file.id
li mimetype #{file.mimetype} a(href=url)= url
li filename #{file.filename}
li password '#{file.password}'
form(method='POST' action='/upload' enctype='multipart/form-data') form(method='POST' action='/upload' enctype='multipart/form-data')
label(for='file_input') 文件 label(for='file_input') 文件
input(id='file_input' name='file' type='file' required) input(id='file_input' name='file' type='file' required)