微信小程序/uniapp實現多圖上傳到七牛雲

前端上傳的圖片很佔用服務器資源,因此尋找解決辦法看到了七牛雲的圖片上傳功能,由於七牛雲只提供了單張圖片上傳的api,我使用循環的方式實現了前端上傳多圖的效果。實現過程中踩到了兩個坑值得記錄一下,第一是循環中的異步回調函數導致的key和token錯位,其次就是回調函數的作用域問題。

前端使用的是dcloud的uniapp框架,大致結構與微信小程序沒有差別,基本上小程序的api在uniapp中也有對應的api。

前端使用

首先下載七牛雲提供的前端sdk,解壓到本地將 qiniuUploader.js 引入到需要上傳圖片的頁面使用。

這裏我放到了components/qiniuUploader目錄下。

<template>
	<view>
		<button type="primary" @click="qupload">選擇圖片</button>
		<button type="primary" @click="test">七牛多圖</button>
	</view>
</template>

<script>
	const qiniuUploader = require("../../components/qiniuUploader");
	export default {
		data() {
			return {
				token: [],
				key: [],
				filePath: []
			}
		},
	methods: {
			qupload() {
				// 選擇圖片
				uni.chooseImage({
					count: 4,
					success: (res) => {
						this.filePath = this.filePath.concat(res.tempFilePaths);
						for (var i = 0; i < 4; i++) {
							// this.key[i] = md5(Math.random().toString(36).substr(2));一開始是在這裏生成後端生成token所需的key,由於沒有考慮到回調函數的異步導致了key和token不匹配造成的上傳失敗,最後通過將key放到後端生成,前端請求後端接口時一起獲取解決了這個問題
							uni.request({
								url: 'http://api.nauzone.cn/?service=',//後端生成key和token的接口
								success: (re) => {
									console.log(re.data.data);
									// this.token.push(re.data.data);
									//將token和key放入數組中備用,這裏還有一個問題就是回調函數的this指向問題,經過經驗事實發現,如果回調函數的格式寫成匿名函數 success:function(){ }的樣式將會導致this指向變爲函數內部,這是將報this沒有token和key的屬性,雖然這已經在全局聲明瞭。寫成success: (re) => { } 則沒有任何問題,此時回調函數內部就是全局。還有一個坑也是回調函數的異步導致的在同一個執行期上下文內,在回調函數的內部push的值在外部不能立即獲取,這裏需要注意一下。
									this.token.push(re.data.data.token);
									this.key.push(re.data.data.key);
									
								}
							});
						}
					}
				});
				
			},
			test() {//循環上傳圖片
				for (var i = 0; i < 4; i++) {
					//console.log(this.filePath[i]);
					
					console.log(this.key[i]);
					console.log(this.token[i]);
					qiniuUploader.upload(this.filePath[i], (res) => {
						console.log(res.imageURL);
					}, (error) => {
						var a = JSON.stringify(error);
						console.log('error: ' + a);
					}, {
						region: 'ECN',
						domain: 'pn7r16wx7.bkt.clouddn.com', // // bucket 域名,下載資源時用到。如果設置,會在 success callback 的 res 參數加上可以直接使用的 ImageURL 字段。否則需要自己拼接
						key: this.key[i], // [非必須]自定義文件 key。如果不設置,默認爲使用微信小程序 API 的臨時文件名
						// 以下方法三選一即可,優先級爲:uptoken > uptokenURL > uptokenFunc
						uptoken: this.token[i],
					});
				}
			}
		}
	</script>

後端token生成

七牛雲上傳要求由key生成一個上傳憑證token,token有3中方法生成並給七牛雲驗證。第一就是由其他程序生成token後在調用時將token一起上傳,第二是在前端構造一個token生成函數,第三是將後端生成token的api地址發給七牛。無論通過那種方式,都要求key和token要一一對應起來,否則將報403錯誤。

我採用的是第一種方法,由後端生成key和token發送給前端,前端接收後在調用時將收到的token和key發給七牛雲即可。後端採用phalapi開源php框架,引入了七牛雲服務器端的sdk後,重寫了一下便能引入實現了。

use App\Common\Qiniu;
/**
     * 七牛圖片文件上傳
     * @desc 只能上傳單個圖片文
     * @return array token  返回七牛雲上傳憑證token
     * @return string key  返回生成token的key
     */
    public function qiniu() {
        $rs = array();
        $rs['key'] = md5(uniqid(microtime(true),true));//生成唯一字符串
        $uploader = new Qiniu('七牛雲ak’,'七牛雲sk');
        $rs['token'] = $uploader->uploadToken('upload',$rs['key']);
        return $rs;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章