uni-app實(shí)現(xiàn)文件上傳功能

uni-app實(shí)現(xiàn)文件上傳功能

目前找到的比較好用的一款第三方插件
文件上傳插件地址 https://ext.dcloud.net.cn/plugin?id=1015
插件下載選擇下載示例項(xiàng)目zip 孽亲,可以直接運(yùn)行項(xiàng)目查看效果

目錄結(jié)構(gòu)如下


20200317231930880.png

index.vue,是使用文件上傳功能的當(dāng)前頁面

@up-success="onSuccess" 是文件上傳成功以后回傳的數(shù)據(jù)

<template>
    <view>
        <l-file ref="lFile" @up-success="onSuccess"></l-file>
        <view class="padding text-center">
            <view class="padding">
                <button @tap="onUpload">上傳</button>
            </view>
        </view>
    </view>
</template>
<script>
    import lFile from '@/components/l-file/l-file.vue'
    export default {
        components:{lFile},
        data() {
            return {
            }
        },
        methods: {
            /* 上傳 */
            onUpload() { 
                this.$refs.lFile.upload({
                    // #ifdef APP-PLUS
                    currentWebview: this.$mp.page.$getAppWebview(),
                    // #endif
                    //非真實(shí)地址尚胞,記得更換
                     url: 'https://www.example.com/upload',
                    //默認(rèn)file,上傳文件的key
                    name: 'uploadFile',
                    // header: {'Content-Type':'類型','Authorization':'token'},
                    //...其他參數(shù)
                });
            },
            onSuccess(res) {
                console.log('上傳成功回調(diào)=====33====',JSON.stringify(res));
                uni.showToast({
                    title: JSON.stringify(res),
                    icon: 'none'
                })
            }
        }
    }
</script>


l-file.vue,是文件上傳功能的封裝組件,最后加載的是index.html文件

wv.overrideUrlLoading 監(jiān)聽返回的文件上傳結(jié)果。

getRequest(url) {  
    let theRequest = new Object(); 
    let index = url.indexOf("?");
    if (index != -1) {  
        let str = url.substring(index+1);  
        let strs = str.split("&");  
        for(let i = 0; i < strs.length; i ++) {  
            theRequest[strs[i].split("=")[0]]=unescape(strs[i].split("=")[1]);  
        } 
    }  
    return theRequest;  
},
appChooseFile({currentWebview,url,name = 'file',header,...formData} = {}) {
    // #ifdef APP-PLUS
    let wv = plus.webview.create("","/hybrid/html/index.html",{
        'uni-app': 'none', //不加載uni-app渲染層框架死遭,避免樣式?jīng)_突
        top: 0,
        height: '100%',
        background: 'transparent'
    },{
        url,
        header,
        key: name,
        ...formData,
    });
    wv.loadURL("/hybrid/html/index.html")
    currentWebview.append(wv);
    wv.overrideUrlLoading({mode:'reject'},(e)=>{
        let {fileName,id} = this.getRequest(e.url);
        return this.onCommit(
        this.$emit('up-success',{fileName,data: {id,statusCode: 200}})
        );
    });
    // #endif
}


index.html 源碼

<!DOCTYPE html>
<html lang="zh-cn">

    <head>
        <meta charset="UTF-8">
        <title class="title">[文件管理器]</title>
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <style type="text/css">
            .content {background: transparent;}
            .fixed {position: fixed;bottom: 0;left: 0;right: 0;width: 100%;}
            .content .mask {top: 0;background: rgba(0,0,0,.4);z-index: 90;}
            .content .file-content {z-index: 91;height: 60px;background: #fff;text-align: center;}
            .btn {position: relative;}
            .btn .file {position: absolute;z-index: 93;left: 0;right: 0;top: 0;bottom: 0;height: 60px;width: 100%;opacity: 0;}
            .btn-bg {margin-top: 10px;background: #0066CC;color: #fff;width: 80%;height: 40px;border: 0;border-radius: 5px;}
            .tis {top: 0;z-index: 95;display: none;justify-content: center;align-items: center;}
            .tis .tis-content {background: #fff;width: 60%;border-radius: 10px;padding: 20px 0;}
            .tis .tis-content img {width: 50px;height: 50px;}
            .tis-progress {margin: 10px 0;color: #999;}
            .cancel-btn {margin-top: 30px;height: 30px;line-height: 1;padding: 0 2em;background: #e3e3e3;color: #898989;border: 0;border-radius: 5px;}
        </style>
    </head>

    <body>
        
        <div class="content">
            
            <div class="fixed mask"></div>
            
            <div align="center" class="fixed tis">
                <div class="tis-content">
                    <div>
                        <img src="../../static/logo.png" >
                    </div>
                    <div class="tis-progress">
                        努力上傳中..
                    </div>
                    <div class="cancel">
                        <button type="button" class="cancel-btn">取消上傳</button>
                    </div>
                </div>
            </div>
            
            <div class="fixed file-content">
                <div class="btn">
                    <button type="button" class="btn-bg">打開文件管理器</button>
                    <input class="file" type="file" />
                </div>
            </div>
        </div>
        
        <script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script>
        <script src="js/h5-uploader.js" type="text/javascript" charset="utf-8"></script>
    </body>

</html>


h5-uploader.js 源碼

負(fù)責(zé)h5代碼上傳文件及其進(jìn)度展示圣猎,及上傳結(jié)果回傳

let mask = document.querySelector(".mask");
let fileDom = document.querySelector(".file");
let tis = document.querySelector(".tis");
let progress = document.querySelector(".tis-progress");
let cancel = document.querySelector(".cancel-btn");


let createUpload = (file, url, key='file', header = {},data = {}) => {
    console.log(`
    上傳地址:${url}\n
    請(qǐng)求頭:${JSON.stringify(header)}\n
    參數(shù):${JSON.stringify(data)}
    `);
    if (!url) {return;}
    tis.style.display = 'flex';
    
    let formData = new FormData();
        formData.append(key, file);
    
    for (let keys in data) {
        formData.append(keys, data[keys]);
    }
    
    let xhr = new XMLHttpRequest();
    xhr.open("POST", url, true);
    
    for (let keys in header) {
        xhr.setRequestHeader(keys, header[keys]);
    }
    xhr.upload.addEventListener("progress", function(event) {
        if(event.lengthComputable){
            let percent = Math.ceil(event.loaded * 100 / event.total) + "%";
            progress.innerText = `努力上傳中..${percent}`;
        }
    }, false);
    
    xhr.ontimeout = function(){
        // xhr請(qǐng)求超時(shí)事件處理
        progress.innerText = '請(qǐng)求超時(shí)';
        setTimeout(()=>{
            tis.style.display = 'none';
            plus.webview.currentWebview().close();
        },1000);
    };
    
    xhr.onreadystatechange = (ev) => {
        
        if(xhr.readyState == 4) {
            console.log('status:'+xhr.status);
            
            if (xhr.status == 200) {
                progress.innerText = '上傳成功';
                console.log('返回?cái)?shù)據(jù):'+xhr.responseText);
                location.href = `callback?fileName=${file.name}&id=${xhr.responseText}`;
                
            }
            else {
                progress.innerText = '上傳失敗了';
            }
            
            setTimeout(()=>{
                tis.style.display = 'none';
                plus.webview.currentWebview().close();
            },1000);
            
        }
    };
    xhr.send(formData);
    
    cancel.addEventListener("click", ()=>{
        xhr.abort();
        plus.webview.currentWebview().close();
    });
}


mask.addEventListener("click", () => {
    plus.webview.currentWebview().close();
});

document.addEventListener('UniAppJSBridgeReady', () => {
    let {url,key,header,formData} = plus.webview.currentWebview();
    fileDom.addEventListener('change', (event) => {
        let file = fileDom.files[0];
        if(file.size > (1024*1024 * 10)) {
            plus.nativeUI.toast('單個(gè)文件不能超過10M,請(qǐng)重新上傳');
            return;
        }
        console.log(file.name);
        createUpload(file, url, key,header,formData);
    }, false);
});

插件地址 https://ext.dcloud.net.cn/plugin?id=1015

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市馋没,隨后出現(xiàn)的幾起案子械蹋,更是在濱河造成了極大的恐慌,老刑警劉巖绸硕,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件堂竟,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡玻佩,警方通過查閱死者的電腦和手機(jī)出嘹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來咬崔,“玉大人税稼,你說我怎么就攤上這事】逅梗” “怎么了郎仆?”我有些...
    開封第一講書人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)甚脉。 經(jīng)常有香客問我丸升,道長(zhǎng),這世上最難降的妖魔是什么牺氨? 我笑而不...
    開封第一講書人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任狡耻,我火速辦了婚禮墩剖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘夷狰。我一直安慰自己岭皂,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開白布沼头。 她就那樣靜靜地躺著爷绘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪进倍。 梳的紋絲不亂的頭發(fā)上土至,一...
    開封第一講書人閱讀 49,929評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音猾昆,去河邊找鬼陶因。 笑死,一個(gè)胖子當(dāng)著我的面吹牛垂蜗,可吹牛的內(nèi)容都是我干的楷扬。 我是一名探鬼主播,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼贴见,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼烘苹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起片部,我...
    開封第一講書人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤镣衡,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后吞琐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體捆探,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年站粟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了黍图。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡奴烙,死狀恐怖助被,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情切诀,我是刑警寧澤揩环,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站幅虑,受9級(jí)特大地震影響丰滑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜倒庵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一褒墨、第九天 我趴在偏房一處隱蔽的房頂上張望炫刷。 院中可真熱鬧,春花似錦郁妈、人聲如沸浑玛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽顾彰。三九已至,卻和暖如春胃碾,著一層夾襖步出監(jiān)牢的瞬間涨享,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來泰國打工仆百, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留灰伟,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓儒旬,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親帖族。 傳聞我的和親對(duì)象是個(gè)殘疾皇子栈源,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350

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

  • uni-app跨平臺(tái)框架官方教程 鏈接:https://ke.qq.com/course/343370 一、框架簡(jiǎn)...
    Neyo_涼閱讀 36,197評(píng)論 0 43
  • 基于Vue的一些資料 內(nèi)容 UI組件 開發(fā)框架 實(shí)用庫 服務(wù)端 輔助工具 應(yīng)用實(shí)例 Demo示例 element★...
    嘗了又嘗閱讀 1,142評(píng)論 0 1
  • 至此,我們完成了插件的使用涣雕,整個(gè)過程我們都是在 HBuilder X 中進(jìn)行艰亮,接下來我們進(jìn)入開發(fā)插件階段。 概述 ...
    TankXie閱讀 4,074評(píng)論 4 6
  • 寫在有道筆記上挣郭,uni項(xiàng)目實(shí)踐迄埃,轉(zhuǎn)過來格式不太好看,先做此記錄吧兑障。 看了uniapp多端開發(fā)侄非,感覺不錯(cuò),還有模板商...
    YellowPoint閱讀 2,358評(píng)論 0 1
  • 01 兒子六歲時(shí)流译,我忽然發(fā)現(xiàn)周圍熟悉的人幾乎都生了二胎逞怨,前幾年賺錢買車買房目標(biāo)實(shí)現(xiàn)階段,沒有放慢腳步去重新設(shè)定人生...
    朵拉朵尚閱讀 501評(píng)論 5 15