两种文件上传的方式
服务端传输
客户端直传
两种传输方式比较
服务端传输,所有客户端的上传请求需发送至业务服务器,再由业务服务器转发至文件服务器,上传结果的返回同样需要业务服务器的转发,这样的操作保证了传输的安全,但却大大提升了业务服务器的压力,增加了传输的时间及成本;
客户直传是由客户端到业务服务器取得文件上传令牌,然后携令牌上传文件至文件服务器,这样很好的保证了安全的同时,极大的提高了传输效率;
客户端直传实现
服务端实现
- 引入七牛的Java SDK
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>7.2.10</version>
</dependency>
- 提供客户端获取upToken接口
@RestController
public class FileUploadApi {
@Value("${qiniu.ak}")
private String QINIU_AK;
@Value("${qiniu.sk}")
private String QINIU_SK;
@Value("${qiniu.bucket}")
private String QINIU_BUCKET;
//获取七牛云上传token
@GetMapping(path = "upToken")
public String getUpToken() {
Auth auth = Auth.create(QINIU_AK, QINIU_SK);
String upToken = auth.uploadToken(QINIU_BUCKET);
return upToken;
}
}
其中BUCKET、AK、SK 在七牛云控制台获取
前端实现
<template>
<div class="app-container">
<form id="fileUploadForm" method="post" action="http://up-z2.qiniu.com">
<input name="file" type="file" />
<input name="accept" type="hidden" />
</form>
<img :src="img" alt="">
<button @click="upload">上传</button>
</div>
</template>
<script>
const qiniu = require('qiniu')
const uuid = require('uuid/v4')
const request = require('../utils/request')
import fileUploadApi from '../api/FileUploadApi'
export default {
name:'UploadFile',
data:function(){
return {
key:uuid(),
upToken:'',
img:'',
}
},
methods:{
upload:function(){
const _this = this;
//上传的文件名使用uuid
_this.key = uuid()
console.log(_this.key)
//获取formData
var formData = new FormData(document.getElementById('fileUploadForm'))
//从服务端获取upToken
fileUploadApi.getUpToken()
.then(function(data){
if(data == null || data.lenth == 0){
return
}
_this.upToken = data.toString()
//fileForm,upToken,key,otherOpt
//上传图片文件
fileUploadApi.upload(formData,_this.upToken,_this.key,null)
.then(function(data){
if (data.key){
//获取七牛云key 并生成图片外链 展示
_this.img = fileUploadApi.getDownloadURL(data.key)
}
})
}).catch(function(){
return
})
}
}
}
</script>
这里主要采用了HTML5 的formData对表单中的file input进行数据提取,提取出的数据通过axios异步提交
import request from '../utils/request'
import global from '../utils/global'
/**
* 文件上传API
*/
export default{
//获取上传upToken
getUpToken:function(){
return request({
url:'/hnister-file-service/upToken',
method:'get'
})
},
//以表单方式上传文件 参考:
//https://developer.qiniu.com/kodo/manual/1272/form-upload
upload: function(fileForm,upToken,key,otherOpt){
if (!otherOpt){
otherOpt = {}
}
fileForm.append('key',key)
fileForm.append('token',upToken)
for(k in Object.keys(otherOpt)){
fileForm.append(k,otherOpt[k])
}
return request({
url:global.address.qiniuUploadURL,
baseURL:'',
method:'post',
data:fileForm,
headers:{'Content-Type':'multipart/form-data'}
})
},
//上传后返回的key 获取文件外链
getDownloadURL:function(key){
return global.address.qiniuDownloadURL + '/' + key;
}
}
文件上传API
import axios from 'axios'
import global from './global'
// 创建axios实例
const service = axios.create({
// baseURL: process.env.BASE_API, // api的base_url
baseURL: global.address.zuul,
timeout: 15000 // 请求超时时间
})
const responseFun = function (response) {
return response.data;
}
// respone拦截器
service.interceptors.response.use(
responseFun,
error => {
return Promise.reject(error)
}
)
export default service;
对axios 进行封装和拦截
const address = {
zuul:'http://localhost:10000',
//七牛云的华南区文件上传地址
qiniuUploadURL:'http://up-z2.qiniu.com',
//我的七牛云图片下载host
qiniuDownloadURL:'http://p4fkxpg80.bkt.clouddn.com',
}
export default{
address
}
保存全局变量