乐趣区

关于vue.js:vue上传图片到七牛云的思路与实现

本文分为思路篇和代码篇,思路篇次要是思路和代码混合,次要重点是解说思路;代码篇是正文和代码联合,次要展现代码.

一、思路篇

办法一:上传图片流程的思路(通过前台上传图片):

1. 接管 token 前的操作

阐明:前台点击上传图片的按钮前, 须要先获取七牛云的 token, 须要的流程如下:

1.1 前台关上本地图片的时候, 须要获取须要获取本地图片的名称(用来赋值给上面的 key, 以便生成 token), 而后发给后盾, 后盾把文件名称(此时文件名倡议进行操作, 重命名)赋值给 key

1.2 后盾依据:key 以及你的七牛云命名空间的名称即:bucket 生成 token 后发送给前台

2. 承受到 token 后的操作

2.1 前台接管到 token, 须要把文件转为字节流 而后把【token】以及【文件字节流】以及【文件名称:key】打包成一个对象, 而后开始发送到七牛云

3. 具体代码:后盾操作

// 须要填写你的 Access Key 和 Secret Key 这个在七牛云 集体核心 > 密钥治理 性能外面
qiniu.conf.ACCESS_KEY = '0kSEeVVtcqWFQ18z0TWlDe6eBC3lFchpHLBNe-_F';// 公钥
qiniu.conf.SECRET_KEY = 'Y2P5am6LWW44yxo2YWwsiY4RteqyFeut58gCHBM_';// 私钥
// 要上传的空间
bucket = 'we-teach';// 我的 bucket 名称, 即文件的命名空间的名称
// 上传到七牛后保留的文件名
key = 'my-nodejs-logo.png';// 此处我间接在前台生成我须要放弃的文件名, 而后发到给后端。也能够把文件名间接发到后端, 让后端解决, 因为前端后端都是我一个人写的, 所以我比拟随便
// 构建上传策略函数, 生成 token 并设置回调的 url 以及须要回调给业务服务器的数据。此处的回调服务器地址须要你的公网服务器地址, 然而我间接在本地操作的, 没有公网地址, 所以就没有改变七牛云的 example 了, 间接 copy
function uptoken(bucket, key) {var putPolicy = new qiniu.rs.PutPolicy(bucket+":"+key);
  putPolicy.callbackUrl = 'http://your.domain.com/callback';
  putPolicy.callbackBody = 'filename=$(fname)&filesize=$(fsize)';
  return putPolicy.token();}
// 生成上传 Token
token = uptoken(bucket, key);// 此处的 token 须要发给前台, 好让前台开始操作, 实现图片上传
console.log("七牛云上传图片的 token:",token);// 后盾代码完结

前台操作
要上传文件的本地门路或者字节流, 尽管七牛云官网文档有说最简略的上传就是本地上传时给一个本地的门路就好了
然而我感觉间接指定本地的图片门路只适宜后盾上传, 不适宜前台, 具体起因见上面的后话
所以本文演示的都是传全副文件数据,而非文件地址。

//1. 选中图片时发送 key,即文件名称给后盾,以便后盾生成 token
this.axios.get('/filename','my-nodejs-logo.png')// filePath_or_stream = './nodejs-logo.png'||filePath_or_stream=readableStream【readableStream 是前台传过来的全副文件的数据流】filePath_or_stream = readableStream;// 应用前台传过来的字节流数据进行赋值
//2. 选中图片后,开始上传前:获取 token
this.axios.get('/up/token').then(res => {console.log(res)
  const formdata = new FormData()//FormData 是浏览器的办法,用于 html 追加表单键值对,具体应用能够看看 MDN 文档,简略介绍看看上面后话我的介绍
  formdata.append('file', req.file)// 往表单上传的数据域追加 file 属性,它的 value 是 req.file。reqreq.file 是咱们本地的文件地址,elementui 的 el-upload 里的 http-request 像咱们本地计算机发动申请数据,会把咱们抉择的文件地址赋值给 req.file(原生的 html 的表单上传属性也能够获取文件的地址)formdata.append('token', res.data)// 往表单上传的数据域追加 token 属性,它的 value 是 res.data,res.data 是后盾在咱们申请 token 时发送过去的数据
  formdata.append('key', keyname)// 往表单上传的数据域追加 key 属性,keyname 是咱们自定义须要保留的文件名称
  // 3. 点击上传时:获取到凭证之后再将文件上传到七牛云空间
  this.axios.post(this.domain, formdata, config).then(res => {
    this.imageUrl = 'http://' + this.qiniuaddr + '/' + res.data.key
    // console.log(this.imageUrl)
  })
})

办法二:上传图片流程的思路(通过后盾上传图片):

1. 接管 token 前的操作
阐明:前台点击上传图片的按钮时,【须要先把本地图片的名称以及图片字节流数据发给后盾】,【或者把批改好后的须要重命名的图片名称以及图片字节流数据发给后盾】, 须要的流程如下:
1.1 前台上传本地图片的时候, 须要获取本地图片的名称(用来赋值给上面的 key, 以便生成 token), 而后同时把图片字节流一并发给后盾, 后盾把文件名(此时文件名倡议进行操作, 重命名)称赋值给 key
1.2 后盾依据:key 以及你的七牛云命名空间的名称即:bucket 生成 token

2. 承受到 token 后的操作
2.1 后盾生成 token 后, 把【token】以及【文件字节流】以及【文件名称:key】打包成一个对象, 而后开始发送到七牛云

3. 具体代码:后盾操作

// 须要填写你的 Access Key 和 Secret Key 这个在七牛云 集体核心 > 密钥治理 性能外面
qiniu.conf.ACCESS_KEY = '0kSEeVVtcqWFQ18z0TWlDe6eBC3lFchpHLBNe-_F';// 公钥
qiniu.conf.SECRET_KEY = 'Y2P5am6LWW44yxo2YWwsiY4RteqyFeut58gCHBM_';// 私钥

// 要上传的空间
bucket = 'we-teach';// 我的 bucket 名称, 即文件的命名空间的名称

// 上传到七牛后保留的文件名
key = 'my-nodejs-logo.png';// 此处我间接在前台生成我须要放弃的文件名, 而后发到给后端。也能够把文件名间接发到后端, 让后端解决, 因为前端后端都是我一个人写的, 所以我比拟随便
// 构建上传策略函数, 生成 token 并设置回调的 url 以及须要回调给业务服务器的数据。此处的回调服务器地址须要你的公网服务器地址,// 然而我间接在本地操作的, 没有公网地址, 所以就没有改变七牛云的 example 了, 间接 copy 没改 function uptoken(bucket, key) {var putPolicy = new qiniu.rs.PutPolicy(bucket+":"+key);
  putPolicy.callbackUrl = 'http://your.domain.com/callback';
  putPolicy.callbackBody = 'filename=$(fname)&filesize=$(fsize)';
  return putPolicy.token();}

// 生成上传 Token
token = uptoken(bucket, key);// 此处的 token 须要依据【前台发送来的图片名称】即:【key】加上【bucket】生成
console.log("七牛云上传图片的 token:",token);

要上传文件的本地门路或者字节流, 尽管七牛云官网文档有说最简略的上传就是本地上传时给一个本地的门路就好了
然而我感觉间接指定本地的图片门路只适宜后盾上传, 不适宜前台, 具体起因见上面的后话
所以本文演示的都是传全副文件数据,而非文件地址
// filePath_or_stream = './nodejs-logo.png'||filePath_or_stream=readableStream【readableStream 是前台传过来的全副文件的数据流】filePath_or_stream = readableStream;// 应用前台传过来的字节流数据进行赋值
// 结构上传函数 uptoken:上传凭证,由 bucket 与咱们传过来的【key 即须要保留的文件的名称】生成。key【key 即须要保留的文件的名称】, //localFile【本地文件,能够是数据流或者地址,本文都是采纳数据流】function uploadFile(uptoken, key, localFile) {var extra = new qiniu.io.PutExtra();
    qiniu.io.putFile(uptoken, key, localFile, extra, function(err, ret) {if(!err) {
        // 上传胜利,解决返回值
        console.log(ret.hash, ret.key, ret.persistentId);       
      } else {
        // 上传失败,解决返回代码
        console.log(err);
      }
  });
}
// 调用 uploadFile 上传
uploadFile(token, key, filePath_or_stream);

前台操作不写,思路篇思路介绍为主。

三、后话

1. 对于 filePath_or_stream

尽管七牛云容许咱们在上传的时候间接在上传本地图片的地址就好了,然而我感觉此种场景只适宜后盾上传,并且后盾上传还依然有所限度,为什么呢?

上面解释:因为咱们上传数据的时候并不是平白无故就能够上传的,须要点对点的传数据。

1.1 情景模仿:

(A 发送数据给 B, 只发送了数据的地址,就相当于咱们只发送了图片地址)假如 A 发送数据给 B, 那么 A 就肯定要把数据拿到手,能力发送给 B, 尽管这里有讲废话的嫌疑,然而确实有情理。

假如咱们上传图片时前台间接发送咱们图片的地址给七牛云,那么七牛云只接管到咱们本地计算机的地址,如:localhost://we-teach/1.png 那么七牛云尽管晓得咱们须要上传的图片的地址,然而却无能为力,首先咱们的本地计算机的 ip 地址不是公网地址,七牛云即便晓得咱们本地的文件存储地址,也无奈从咱们的计算机获取数据 那么如果是后盾发送的话,须要后盾部署在一个公网 IP 的服务器下面,此时发送地址给七牛云,那么他接管到申请后就能够从咱们的服务器拉取数据。当然这些只是我猜想的,因为具体技术我也不太分明,还是小菜鸡一个。

1.2 情景模仿:

(A 发送数据给 B, 发送了数据的全副信息,就相当于咱们把图片全副发送过来了)所以我感觉既然只传地址的原理我搞不太懂,那么把数据全副发过来就能够了,这个原理简略且易懂,A 拿着数据全副送到 B 门口,那么 B 就必定能拿到了。所以本文传过来的数据都是图片的全副信息,而非本地地址而已。

1.3 前台只传本地地址的状况下,能不能让七牛云也晓得咱们发送图片的具体信息?

这个能够用 FormData 对象,这个是浏览器的接口,原生 js 没有,就是说这个办法只能用于 html 网页 formData,就像他的名字一样,表单数据,它能够用来给表单数据追加键值对。

具体用法能够看看 MDN 文档:https://developer.mozilla.org…

FormData 是一个构造函数,应用它须要 new 一个实例 const formdata = new FormData(),而后把咱们本地的图片地址传入进去:formdata.append(‘file’, req.file),那么表单数据对象就多了一个 file 的属性,他的值就是 req.file 应用 elementUi 的上传组件,或者原生的 html 的上传的元素,情理都一样能够应用 formData。

小 demo:

 <template>
  <!-- upload -->
  <div class="upload">
    <el-upload
      class="avatar-uploader"
      :action= domain
      :http-request = upqiniu
      :show-file-list="false"
      :before-upload="beforeUpload">
      <img v-if="imageUrl" :src="imageUrl" class="avatar">
      <i v-else class="el-icon-plus avatar-uploader-icon"></i>
    </el-upload>
  </div>
</template>
<script>
export default {data () {
    return {
      imageUrl: '',
      token: {},
      // 七牛云的上传地址,依据本人所在地区抉择,我这里是华南区
      domain: 'https://upload-z2.qiniup.com',
      // 这是七牛云空间的外链默认域名
      qiniuaddr: 'p3z6q1uw1.bkt.clouddn.com'
    }
  },
  methods: {
    // 上传文件到七牛云
    upqiniu (req) {console.log(req)
      const config = {headers: {'Content-Type': 'multipart/form-data'}
      }
      let filetype = ''if (req.file.type ==='image/png') {filetype = 'png'} else {filetype = 'jpg'}
      // 重命名要上传的文件
      const keyname = 'lytton' + new Date() + Math.floor(Math.random() * 100) + '.' + filetype
      // 从后端获取上传凭证 token
      this.axios.get('/up/token').then(res => {console.log(res)
        const formdata = new FormData()
        formdata.append('file', req.file)// 追加 file 数据,req.file 是咱们本地的文件地址,elementui 的 el-upload 里的 http-request 像咱们本地计算机发动申请数据,会把咱们抉择的文件地址赋值给 req.file
        formdata.append('token', res.data)
        formdata.append('key', keyname)
        // 获取到凭证之后再将文件上传到七牛云空间
        this.axios.post(this.domain, formdata, config).then(res => {
          this.imageUrl = 'http://' + this.qiniuaddr + '/' + res.data.key
          // console.log(this.imageUrl)
        })
      })
    },
    // 验证文件合法性
    beforeUpload (file) {
      const isJPG = file.type === 'image/jpeg' || file.type === 'image/png'
      const isLt2M = file.size / 1024 / 1024 < 2
      if (!isJPG) {this.$message.error('上传头像图片只能是 JPG 格局!')
      }
      if (!isLt2M) {this.$message.error('上传头像图片大小不能超过 2MB!')
      }
      return isJPG && isLt2M
    }
  }
}
</script>
<style scoped>
.upload {
  width: 600px;
  margin: 0 auto;
}
.avatar-uploader .el-upload {
  border: 5px dashed #ca1717 !important;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.avatar-uploader .el-upload:hover {border-color: #409EFF;}
.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  line-height: 178px;
  text-align: center;
}
.avatar {
  width: 178px;
  height: 178px;
  display: block;
}
</style> 

2. 对于 qiniu.io.PutExtra()

var extra = new qiniu.io.PutExtra();//extra 官网文档尽管没有明确阐明,

然而有一个 example,我预计它是用来设置参数的可选值 例子:

集体感觉设置了扩大参数,而后执行回调操作时,它会在七牛云本来返回的原始 json 数据响应下面加上咱们自定义的参数。

var putExtra = new qiniu.resume_up.PutExtra(); // 扩大参数

putExtra.params = {“x:name”: “”, “x:age”: 27,}

putExtra.fname = ‘testfile.mp4’;

退出移动版