使用Vue和Koa实现手动图片上传,上传过程需进行token验证,验证token有效才能完成文件上传
时间: 2024-05-02 21:17:52 浏览: 8
前端部分:
1. 安装并引入Vue和Axios库
```
npm install vue axios --save
```
```javascript
import Vue from 'vue'
import axios from 'axios'
Vue.prototype.$axios = axios
```
2. 创建一个上传组件
```vue
<template>
<div>
<input type="file" @change="handleChange" />
<button @click="handleUpload">上传</button>
</div>
</template>
<script>
export default {
data() {
return {
file: null,
token: '',
}
},
methods: {
handleChange(e) {
this.file = e.target.files[0]
},
async handleUpload() {
if (!this.token) {
alert('请先获取token')
return
}
const formData = new FormData()
formData.append('file', this.file)
try {
const res = await this.$axios.post('/upload', formData, {
headers: {
Authorization: `Bearer ${this.token}`,
'Content-Type': 'multipart/form-data',
},
})
console.log(res.data)
} catch (err) {
console.log(err)
}
},
},
}
</script>
```
后端部分:
1. 安装并引入Koa和Koa-router库
```
npm install koa koa-router --save
```
```javascript
const Koa = require('koa')
const Router = require('koa-router')
const app = new Koa()
const router = new Router()
app.use(router.routes())
app.listen(3000, () => {
console.log('Server is running at http://localhost:3000')
})
```
2. 创建获取token的路由
```javascript
router.get('/token', (ctx) => {
ctx.body = { token: 'mytoken' }
})
```
3. 创建上传文件的路由
```javascript
const fs = require('fs')
const path = require('path')
const util = require('util')
const multer = require('@koa/multer')
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, path.resolve(__dirname, 'uploads'))
},
filename: (req, file, cb) => {
cb(null, `${Date.now()}-${file.originalname}`)
},
})
const upload = multer({ storage: storage })
router.post('/upload', upload.single('file'), async (ctx) => {
const { file } = ctx.req
console.log(file)
const unlink = util.promisify(fs.unlink)
await unlink(file.path)
ctx.body = { message: '文件上传成功' }
})
```
4. 创建token验证中间件
```javascript
const jwt = require('jsonwebtoken')
const secret = 'mysecret'
const auth = async (ctx, next) => {
const token = ctx.headers.authorization.replace('Bearer ', '')
try {
const decoded = jwt.verify(token, secret)
if (decoded.exp <= Date.now() / 1000) {
ctx.status = 401
ctx.body = { message: 'token已过期,请重新登录' }
} else {
await next()
}
} catch (err) {
console.log(err)
ctx.status = 401
ctx.body = { message: 'token无效,请重新登录' }
}
}
router.use(auth)
```
完整代码:
前端部分
```vue
<template>
<div>
<input type="file" @change="handleChange" />
<button @click="getToken">获取token</button>
<button @click="handleUpload">上传</button>
</div>
</template>
<script>
export default {
data() {
return {
file: null,
token: '',
}
},
methods: {
handleChange(e) {
this.file = e.target.files[0]
},
async getToken() {
try {
const res = await this.$axios.get('/token')
this.token = res.data.token
} catch (err) {
console.log(err)
}
},
async handleUpload() {
if (!this.token) {
alert('请先获取token')
return
}
const formData = new FormData()
formData.append('file', this.file)
try {
const res = await this.$axios.post('/upload', formData, {
headers: {
Authorization: `Bearer ${this.token}`,
'Content-Type': 'multipart/form-data',
},
})
console.log(res.data)
} catch (err) {
console.log(err)
}
},
},
}
</script>
```
后端部分
```javascript
const Koa = require('koa')
const Router = require('koa-router')
const jwt = require('jsonwebtoken')
const fs = require('fs')
const path = require('path')
const util = require('util')
const multer = require('@koa/multer')
const app = new Koa()
const router = new Router()
const secret = 'mysecret'
const auth = async (ctx, next) => {
const token = ctx.headers.authorization.replace('Bearer ', '')
try {
const decoded = jwt.verify(token, secret)
if (decoded.exp <= Date.now() / 1000) {
ctx.status = 401
ctx.body = { message: 'token已过期,请重新登录' }
} else {
await next()
}
} catch (err) {
console.log(err)
ctx.status = 401
ctx.body = { message: 'token无效,请重新登录' }
}
}
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, path.resolve(__dirname, 'uploads'))
},
filename: (req, file, cb) => {
cb(null, `${Date.now()}-${file.originalname}`)
},
})
const upload = multer({ storage: storage })
router.get('/token', (ctx) => {
const token = jwt.sign({ username: 'admin' }, secret, { expiresIn: '1h' })
ctx.body = { token }
})
router.post('/upload', upload.single('file'), async (ctx) => {
const { file } = ctx.req
console.log(file)
const unlink = util.promisify(fs.unlink)
await unlink(file.path)
ctx.body = { message: '文件上传成功' }
})
router.use(auth)
app.use(router.routes())
app.listen(3000, () => {
console.log('Server is running at http://localhost:3000')
})
```