このプロジェクトでは、写真をアップロードしてフロントエンドに表示する必要があります。そのために、自分で写真関連の練習をします。とても面白いので、共有します。
実装方法:サーバー側の処理方法は、フロントエンドでアップロードしたファイルをサーバー側にローカルに保存し、ファイル名を変更して、サーバー側の画像のパスをテーブルに保存することです。フロントエンドが画像アドレスを要求したら、サーバー側に移動してファイルを検索します。そして、フロントエンドディスプレイに戻ります。
ルートフォルダの下に新しいcommon.jsファイルを作成します
//common.js
//导入所需模块
const router = require('koa-router')()
const api = require('../controllers/api')
const common = require('../util/comon')
const path = require('path')
const fs = require('fs')
const formidable = require('formidable')
const MimeLookup = require('mime-lookup')
const mime = new MimeLookup(require('mime-db'))
router.prefix('/common')
画像をアップロード
//common.js
//上传图片
router.post('/addUploadImg', async (ctx, next) => {
console.log(ctx.req)
let form = new formidable.IncomingForm()
form.hash = "md5"
form.multiples = false //默认只能上传一个文件,更多form的配置参考node-formidable
form.maxFileSize = 2 * 1024 * 1024 //设置文件最大不超过2M
let type = ['image/png','image/gif','image/jpg','image/jpeg','image/webp']//支持上传的图片类型
function formImage() {
return new Promise((resolve, reject) => {
form.parse(ctx.req, async function (err, fields, files) {
//注意:跟express有差异,这里要传入ctx.req
let file = files['file']
if (file) {
let flag = await common.checkFile(file.type, file.size) //校验文件的大小和类型
console.log('校验通过'+flag)
if (flag) {
//文件校验通过
const oldpath = file['_writeStream'].path //系统缓存上传的文件地址
const dir = path.join(__dirname, `../common/upload/img`)
const fileFormat = file.name.split('.')
file.name = `${
file.hash}_${
Date.now()}.${
fileFormat[fileFormat.length - 1]}` //通过file.hash加时间戳生成文件名
const newpath = `common/upload/img/${
file.name}`
if (!fs.existsSync(dir)) {
//先判断文件夹名是否存在,不存在则生成根据XXX生成对应的文件夹
fs.mkdirSync(dir)
}
//如果是非WINDOWS系统,可以用fs.renameSync()来实现,这里为了兼容用了node的pipe来实现
let readStream = fs.createReadStream(oldpath)
let writeStream = fs.createWriteStream(newpath)
readStream.pipe(writeStream) //这里文件已经上传成功
resolve(ctx.origin + "/" + newpath) //返回完整的文件地址
} else {
reject(null)
}
} else {
reject(null)
}
})
})
}
await formImage()
.then(res => {
ctx.body = {
code: 200,
status: 200,
data: res,
message:'上传成功'
}
}).catch(err => {
ctx.body = {
code: 400,
status: 200,
data: {
},
message:'上传失败'
}
}
)
})
画像をダウンロード
//common.js
//显示图片
router.get('/upload/img/:imgUrl', async (ctx, next) => {
url=ctx.url
let index = url.lastIndexOf('/')
imgUrl = url.substring(index + 1, url.length)
let filePath = path.join(__dirname, `../common/upload/img/${
imgUrl}`)
file = fs.readFileSync(filePath)//读取文件
// console.log(await watermark.addWatermark(file, options))
let mimeType = mime.lookup(filePath) //读取图片文件类型
ctx.set('content-type', mimeType) //设置返回类型
ctx.body = file //返回图片
})
ここでのダウンロードは、サーバーが実際にフロントエンドからのこのアドレス要求に応答する必要があるときに、フロントエンドがイメージリンクを取得し、直接img src = "https://***/upload/img.123sdjfhg.png"を取得することを意味します。上記は受信です。リクエスト後、サーバーにアクセスして画像を取得して読み取り、ファイルをフロントエンドに返します。トークンの検証を実行してAPIを要求できると仮定すると、「/ common / upload /」インターフェイスのルートをホワイトリスト(トークンなし)に入れることをお勧めします。
ファイル構造
プロジェクトで提示される最終的な構造は次のとおりです。これ
までのところ、フロントエンドイメージのアップロードとダウンロードの要件は完了しています。ご覧いただきありがとうございます。