uniapp 上傳文件到阿里oss藤抡,僅針對(duì)app而言

一侠碧、 摘要

阿里oss提供了兩種上傳方式到云存儲(chǔ)一種是在Header中包含簽名,一種是在URL中包含簽名缠黍。區(qū)別如下

oss上傳方式.png

在URL中包含簽名
Header中包含簽名

二弄兜、 uniapp提供的上傳方式

  1. uni.uploadFile(OBJECT)

重點(diǎn)說明,這個(gè)api是將本地資源上傳到開發(fā)者服務(wù)器瓷式,客戶端發(fā)起一個(gè) POST 請(qǐng)求替饿,其中 content-type 為 multipart/form-data。并且不可更改贸典,是不可更改视卢,網(wǎng)上很多教程修改Method方法,實(shí)際操作后廊驼,并不可行据过。

  1. uni.request(OBJECT)

重點(diǎn)說明,這個(gè)api妒挎,可以自定義很多Method方法绳锅,但是data的請(qǐng)求的參數(shù)是
Object/String/ArrayBuffer 并且App不支持ArrayBuffer類型

上傳方式講解

  • 有了以上兩個(gè)重要的前提分析后,我們來說一下酝掩,在app上鳞芙,如何使用uniapp進(jìn)行文件上傳
  • 首先基于oss的上傳方式,由于我這里用的是Header中包含簽名的方式上傳的,所以积蜻,只能使用PUT進(jìn)行文件上傳闯割。
    翻閱各種資料后,發(fā)現(xiàn)竿拆,uniapp并沒有很友好的支持PUT上傳文件的方式。插件市場(chǎng)大部分也并不能滿足需求宾尚。這里提一句OSS不支持同時(shí)在URL和Header中包含簽名只能選一種丙笋。所以插件市場(chǎng)上的那些插件,要視情況使用煌贴。
    OSS不支持同時(shí)在URL和Header中包含簽名.png
  • 因?yàn)閡niapp對(duì)put上傳文件的支持有限御板,所以,最終采用內(nèi)嵌webview+XMLHttpRequest的方式來進(jìn)行PUT中的文件上傳牛郑。
  • 由于怠肋,文件選擇我這里使用的是 uni.chooseImage(OBJECT)。這里有個(gè)坑淹朋,當(dāng)前api返回的文件笙各。并不能直接使用put上傳到oss。補(bǔ)充一點(diǎn)础芍,如果使用h5里面的<input type='file'/>標(biāo)簽回調(diào)的文件是可以上傳的杈抢。由于我這里有樣式的要求,所以仑性,并沒有直接使用input標(biāo)簽惶楼。
  • 基于以上,查看相關(guān)文檔后诊杆,發(fā)現(xiàn)使用plus.io.resolveLocalFileSystemURL可以把本地文件路徑轉(zhuǎn)為File對(duì)象
    resolveLocalFileSystemURL
    resolveLocalFileSystemURL.png
  • 這里還有一個(gè)坑歼捐,由于XMLHttpRequest/send(body),對(duì)body的格式有要求晨汹,所以豹储,我們使用plus獲取到的File文件依然不能直接使用。

在XHR請(qǐng)求中要發(fā)送的數(shù)據(jù)體. 可以是:
可以為 Document, 在這種情況下宰缤,它在發(fā)送之前被序列化.
XMLHttpRequestBodyInit, 從 per the Fetch spec (規(guī)范中)可以是 Blob, BufferSource (en-US), FormData, URLSearchParams, 或者 USVString 對(duì)象.
如果body沒有指定值颂翼,則默認(rèn)值為 null .

  • 翻閱各種資料后,發(fā)現(xiàn)慨灭,可以把File對(duì)象重新轉(zhuǎn)換成XMLHttpRequest可識(shí)別的格式
//base64編碼格式轉(zhuǎn)file格式
                    var aa = evt.target.result;
                    var arr = aa.split(','),
                        mime = arr[0].match(/:(.*?);/)[1],
                        bstr = atob(arr[1]),
                        n = bstr.length,
                        u8arr = new Uint8Array(n);
                    while (n--) {
                        u8arr[n] = bstr.charCodeAt(n);
                    }
                    var fileResult = new File([u8arr], "filename.jpg", {
                        type: mime
                    });

最終的fileResult就是XMLHttpRequest可識(shí)別的文件對(duì)象了

轉(zhuǎn)換文件的完整代碼

document.addEventListener('UniAppJSBridgeReady', () => {
    let {
        res = {},
            header,
            fileList
    } = plus.webview.currentWebview();
    var uploadPromise = []
    console.log("傳遞的參數(shù)" + JSON.stringify(fileList))
        //res 為oss下發(fā)的預(yù)上傳的地址
        //header為oss需要添加的請(qǐng)求頭application/octet-stream
        //fileList 本地文件路徑集合朦乏。我這里為了演示,就用了第一個(gè)地址氧骤,實(shí)際項(xiàng)目中呻疹,可以使用批量上傳
    document.addEventListener("plusready", onPlusReady(res, header, fileList[0].path), false);
});

// 擴(kuò)展API加載完畢,現(xiàn)在可以正常調(diào)用擴(kuò)展API
function onPlusReady(res, header, filePath) {
    var uploadPromise = []
    plus.io.resolveLocalFileSystemURL(filePath, function(entry) {
        res.forEach((item, i) => {
            console.log("》》》預(yù)上傳" + JSON.stringify(item))
            console.log("》》》預(yù)上傳文件" + JSON.stringify(entry.isFile))
            entry.file(function(file) {
                var fileReader = new plus.io.FileReader();
                console.log("getFile:" + JSON.stringify(file));
                fileReader.readAsDataURL(
                    file); //以BASE64編碼格式讀取文件                                    
                fileReader.onloadend = function(evt) {
                    // console.log("evt.target" + evt.target);
                    // console.log("evt.target.result len = " +evt.target.result.length);
                    // console.log("evt.target.result  = " +evt.target.result);

                    //base64編碼格式轉(zhuǎn)file格式
                    var aa = evt.target.result;
                    var arr = aa.split(','),
                        mime = arr[0].match(/:(.*?);/)[1],
                        bstr = atob(arr[1]),
                        n = bstr.length,
                        u8arr = new Uint8Array(n);
                    while (n--) {
                        u8arr[n] = bstr.charCodeAt(n);
                    }
                    var fileResult = new File([u8arr], "filename.jpg", {
                        type: mime
                    });
                    uploadPromise[i] = createUpload(fileResult, {
                        url: item.uploadUrl,
                        header: header
                    })

                }
            });



        })

        Promise.all(uploadPromise).then((res) => {
            console.log("全部上傳成功了" + JSON.stringify(res))
            location.href =
                `callback?fileName=1233232323`;
        }).catch((res) => {

        })

    }, function(e) {
        console.log("Resolve file URL failed: " + e.message);
    });
}

項(xiàng)目完整源碼筹陵,待補(bǔ)充

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末刽锤,一起剝皮案震驚了整個(gè)濱河市镊尺,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌并思,老刑警劉巖庐氮,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異宋彼,居然都是意外死亡弄砍,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門输涕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來音婶,“玉大人,你說我怎么就攤上這事莱坎∫率剑” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵檐什,是天一觀的道長(zhǎng)碴卧。 經(jīng)常有香客問我,道長(zhǎng)厢汹,這世上最難降的妖魔是什么螟深? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮烫葬,結(jié)果婚禮上界弧,老公的妹妹穿的比我還像新娘。我一直安慰自己搭综,他們只是感情好垢箕,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著兑巾,像睡著了一般条获。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蒋歌,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天帅掘,我揣著相機(jī)與錄音,去河邊找鬼堂油。 笑死修档,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的府框。 我是一名探鬼主播吱窝,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了院峡?” 一聲冷哼從身側(cè)響起兴使,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎照激,沒想到半個(gè)月后发魄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡俩垃,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年欠母,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吆寨。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖踩寇,靈堂內(nèi)的尸體忽然破棺而出啄清,到底是詐尸還是另有隱情,我是刑警寧澤俺孙,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布辣卒,位于F島的核電站,受9級(jí)特大地震影響睛榄,放射性物質(zhì)發(fā)生泄漏荣茫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一场靴、第九天 我趴在偏房一處隱蔽的房頂上張望啡莉。 院中可真熱鬧,春花似錦旨剥、人聲如沸咧欣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)魄咕。三九已至,卻和暖如春蚌父,著一層夾襖步出監(jiān)牢的瞬間哮兰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工苟弛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留喝滞,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓嗡午,卻偏偏與公主長(zhǎng)得像囤躁,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

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