taro + react hooks + oss小程序上傳

最近在做一個新項目,用到了taro + react hooks + oss小程序上傳。今天就來分享一下其中的技術(shù),目前來看,taro+ react hooks做的小程序很多框架不兼容,尤其是UI框架,能夠打包成功的很少。試了只有@nutui/nutui-react-taro 和?taro-ui@3.1.0-beta.2在小程序執(zhí)行時打包成功,當(dāng)然了,小程序只需要在微信開發(fā)者工具上傳即可,不需要打包,之前在這里的糾結(jié)的原因是習(xí)慣了build,尷尬了。

1、按照taro官方文檔構(gòu)建一個新項目,config配置添加別名配置如下:

alias: {

'@': path.resolve(__dirname, '..', 'src'),

? '@/images': path.resolve(__dirname, '..', 'src/images'),

? '@/assets': path.resolve(__dirname, '..', 'src/assets'),

? '@/components': path.resolve(__dirname, '..', 'src/components'),

? //'@/constants': path.resolve(__dirname, '..', 'src/constants'),

//'@/reducers': path.resolve(__dirname, '..', 'src/reducers'),

? '@/common': path.resolve(__dirname, '..', 'src/common'),

? '@/utils': path.resolve(__dirname, '..', 'src/utils')

},

2、把需要調(diào)用的api封裝在src/api

import { toQueryString }from '@/utils/filter'

import service from '@/utils/request';

//特殊請求加上這段編碼

const otherHeader = {'Content-Type':'application/x-www-form-urlencoded', 'Accept':'*/*' }

//獲取oss的信息

export const ossGetAccessUrl = (params, headers) => {

return service({

method:'GET',

? ? url:'/oss/token',

? ? data: params,

? ? headers: headers

})

}

3、把全局主題色封裝在common/theme.scss下

@charset "UTF-8";

//默認(rèn)全局背景主題色!default

$default-background:#F6F6F7;

//默認(rèn)字體、按鈕背景主題色

$default-primary:#52A86A;

4、把全局組件封裝在components下

5、把需要過濾的封裝在utils/filter下

// 將一個對象轉(zhuǎn)成QueryString

export const toQueryString = (obj) => {

if (!obj)return "";

? ? return cleanArray(

Object.keys(obj).map(key => {

if (obj[key] ===undefined)return "";

? ? ? ? ? ? return encodeURIComponent(key) +"=" +encodeURIComponent(obj[key]);

? ? ? ? })

).join("&");

}

6、把請求攔截封裝在utils/request

import Taro from '@tarojs/taro'

const baseURL ='https://xxx.xxx.com/'

let token ='xxxxxxxx'

let flag =true;

export const service = (parmas) => {

parmas.headers['token'] = token;

? let result =new Promise((resolve, reject) => {

Taro.request({

url: baseURL + parmas.url,?

? ? ? data: parmas.parmas,

? ? ? method:parmas.method ,

? ? ? header: {

...{

'content-type':'application/json' // 默認(rèn)值

? ? ? ? }, ...parmas.headers

? ? ? },

? ? ? success:function (response) {

if (response.statusCode && response.statusCode !==200) {

if (flag) {

Taro.showToast({

title:JSON.stringify(response.data.message),

? ? ? ? ? ? ? icon:'none'

? ? ? ? ? ? })

flag =false;

? ? ? ? ? ? setTimeout(() => {

flag =true;

? ? ? ? ? ? }, 1000)

}

}

if (response.statusCode ===200) {

resolve(response.data)

}else {

reject();

? ? ? ? }

},

? ? ? fail(e:any) {

let message ="";

? ? ? ? switch (e.status) {

case 400:

message ="請求錯誤";

break;

? ? ? ? ? case 401: {

message ="未授權(quán),請登錄";

break;

? ? ? ? ? }

case 403:

message ="沒有權(quán)限,拒絕訪問";

break;

? ? ? ? ? case 404:

message =`請求地址出錯`;

break;

? ? ? ? ? case 500:

message ="服務(wù)器內(nèi)部錯誤";

break;

? ? ? ? ? case 501:

message ="服務(wù)未實現(xiàn)";

break;

? ? ? ? ? case 502:

message ="網(wǎng)關(guān)錯誤";

break;

? ? ? ? ? case 503:

message ="服務(wù)不可用";

break;

? ? ? ? ? case 504:

message ="網(wǎng)關(guān)超時";

break;

? ? ? ? ? case 505:

message ="HTTP版本不受支持";

break;

? ? ? ? ? default:

break;

? ? ? ? }

if (flag) {

Taro.showToast({

title: message,

? ? ? ? ? ? icon:'none'

? ? ? ? ? })

flag =false;

? ? ? ? ? setTimeout(() => {

flag =true;

? ? ? ? ? }, 1000)

}

reject(e)

}

})

})

return result;

}


下面來講封裝小程序上傳圖片到oss,因為小程序上傳的圖片與h5或web端不一樣,沒有file的概念,就需要看阿里云文檔踩坑

1、封裝stsToken,需要通過加密等方式得到signature,policy,x-oss-security-token

import cryptofrom 'crypto-js';

import {Base64}from 'js-base64';

// 計算簽名。

function computeSignature(accessKeySecret, canonicalString) {

return crypto.enc.Base64.stringify(crypto.HmacSHA1(canonicalString, accessKeySecret));

}

const date =new Date();

date.setHours(date.getHours() +1);

const policyText = {

expiration: date.toISOString(), // 設(shè)置policy過期時間。

? conditions: [

// 限制上傳大小。

? ? ["content-length-range", 0, 1024 *1024 *1024],

? ],

};

export const getFormDataParams =async (credentials) => {

const policy = Base64.encode(JSON.stringify(policyText))// policy必須為base64的string。

? const signature =computeSignature(credentials.AccessKeySecret, policy)

const formData = {

OSSAccessKeyId: credentials.AccessKeyId,

? ? signature,

? ? policy,

? ? 'x-oss-security-token': credentials.SecurityToken

? }

return formData

}

2、封裝Taro.uploadFile上傳方法,傳入host、signature、OSSAccessKeyId、policy、key、filePath

import Taro from "@tarojs/taro";

export const wxUpload = (data) => {

const host = data.host;

? const signature = data.signature;

? const ossAccessKeyId = data.OSSAccessKeyId;

? const policy = data.policy;

? const key = data.key;

? const securityToken = data['x-oss-security-token'];

? const filePath = data.filePath; // 待上傳文件的文件路徑。

? let result =new Promise((resolve, reject) => {

Taro.uploadFile({

url: host, // 開發(fā)者服務(wù)器的URL。

? ? ? filePath: filePath,

? ? ? name:'file', // 必須填file。

? ? ? formData: {

name: filePath,

? ? ? ? key,

? ? ? ? policy,

? ? ? ? OSSAccessKeyId: ossAccessKeyId,

? ? ? ? signature,

? ? ? ? success_action_status:"200",

? ? ? ? 'x-oss-security-token': securityToken// 使用STS簽名時必傳。

? ? ? },

? ? ? success: (res) => {

console.log(res)

if (res.statusCode ===200) {

Taro.showToast({title:'上傳成功', icon:'none'})

resolve(host +'/' + key);

? ? ? ? }

},

? ? ? fail: err => {

reject(null)

Taro.showToast({title:'上傳失敗', icon:'none'})

return null;

? ? ? }

});

? })

return result;

}

3、封裝osstoken獲取以及圖片上傳調(diào)用,在選完圖片后會調(diào)用一次ossGetAccessUrl,可優(yōu)化為進(jìn)入首頁調(diào)用,放在dva中緩存起來ossGetAccessUrl,考慮到oss的token可能會失效,所以我這里每次上傳都調(diào)用一次

import {randomString, filterUTCNo}from './filter'

import OSS from 'ali-oss';

import Taro from "@tarojs/taro";

import {getFormDataParams}from './sts'

import {wxUpload}from './wxUpload'

import {ossGetAccessUrl}from '@/api/home'

class MyUploadAdapterAll {

constructor(params) {

// 要在上載期間使用的文件加載器實例

? ? this.file = params.file

? ? this.ossGetAccessUrlData = {}

}

async getAccessUrl() {

if (!this.file) {

return

? ? }

try {

Taro.showLoading()

let res =await ossGetAccessUrl({}, {})

Taro.hideLoading()

if (res.code ===200) {

? ? ? ? let dataParams:any =await getFormDataParams({

AccessKeySecret: res.data.accessKeySecret,

? ? ? ? ? AccessKeyId: res.data.accessKeyId,

? ? ? ? ? SecurityToken: res.data.securityToken,

? ? ? ? })

dataParams.key =`${filterUTCNo(new Date())}/${randomString(8)}_${Date.now()}.${this.file.split('.')[this.file.split('.').length -1]}`

? ? ? ? dataParams.host ='https://' + res.data.bucket +'.' + res.data.endPoint.split('//')[1];

? ? ? ? dataParams.filePath =this.file;

? ? ? ? console.log(dataParams)

return await wxUpload(dataParams);

? ? ? }

}catch (e) {

? ? ? console.log(e)

}

}

}

export default MyUploadAdapterAll

4、在頁面中引入調(diào)用

import MyUploadAdapterAllfrom "@/utils/uploadAll";

Taro.chooseImage({

count:1, // 默認(rèn)9

? sizeType: ['original', 'compressed'], // 可以指定是原圖還是壓縮圖,默認(rèn)二者都有

? sourceType: ['album', 'camera'], // 可以指定來源是相冊還是相機(jī),默認(rèn)二者都有,在H5瀏覽器端支持使用 `user` 和 `environment`分別指定為前后攝像頭

? success:async (res) => {

console.log(res)

const myUploadAdapter =new MyUploadAdapterAll({

dir:'dev',

? ? ? file: res.tempFilePaths[0]

})

let url:string =await myUploadAdapter.getAccessUrl()

if (url) {

console.log(url)

}

}

})

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,345評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,494評論 3 416
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,283評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,953評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,714評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,410評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,940評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,776評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,210評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,654評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內(nèi)容