天天看點

【方法】移動端H5如何調用相冊和相機上傳圖檔、音頻、視訊

在移動端上傳圖檔方法很簡單,使用HTML5中的input:file供檔案上傳。

《一》常用屬性值:

1、accept:規定檔案上傳來送出的檔案類型,此屬性隻能和type:file配合使用

比如:

<input type="file" name="pic" id="pic" accept="image/gif, image/jpeg" /> // 這裡規定了隻接受GIF和JPEG格式圖像      

如果不限制圖像的格式,可以寫成如下:

<input type="file" accept="image/*" capture="camera">  // 不過其實應該避免使用該屬性,應該在伺服器端驗證檔案上傳      

2、multiple:多檔案上傳,比如一次選擇多張圖檔上傳

<input id="fileId2" type="file" multiple="multiple" name="file" />      

《二》上傳圖檔、視訊、音頻方法

<input type="file" accept="image/*" capture="camera">  // 調取圖檔
<input type="file" accept="video/*" capture="camcorder">  // 調取視訊
<input type="file" accept="audio/*" capture="microphone">  // 調取音頻      

在使用上傳檔案或圖檔的時候,IOS和安卓的展現方式有點不同,多環境測試如下:

安卓:

【微信】:  有capture,調相機;           無capture,相冊相機一起調
【QQ】:    有captrue,相冊相機一起調;   無capture,調相冊
【浏覽器】: 有capture,調相機;         無capture,相冊相機一起調      

IOS:

【微信】:  有capture,調相機;   無capture,相冊相機一起調
【QQ】:    有capture,調相機;  無capture,相冊相機一起調
【浏覽器】: 有capture,調相機;  無capture,相冊相機一起調      

上述可以看到,IOS表現一緻,不加capture屬性的時候,會同時調用相冊和相機。

是以如果想要在任何環境下都同時調用相冊和相機,隻需要在實際開發過程中判斷是否是安卓移動裝置且處于QQ環境,然後手動添加capture屬性即可。

js判斷目前頁面是安卓/IOS、微信/QQ環境...

《三》讀取input上傳的圖檔,并将其展示

知識點:FileReader

// 構造方法
var reader = new FileReader();

// 讀取檔案中的資料,FileReader提供如下方法:
readAsText(file, encoding); // 以純文字的形式讀取檔案,并将讀取到文本儲存在result屬性中。第二個參數指定編碼類型,可選
readAsDataURL(file); // 以資料URL的形式讀取檔案,并儲存在result屬性中
readAsBinaryString(file); // 讀取檔案并将一個字元串儲存在result屬性中,字元串中每一個字元表示一個位元組
readAsArrayBuffer(file); // 将一個包含檔案内容的ArrayBuffer儲存在result中      

是以,我們利用readDataURL(file)方法将圖檔進行展示:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>上傳圖檔檔案并回顯</title>
</head>

<body>
   <input type="file" id="#file" multiple>
    <div class="show-box"></div>
    <script>
        var input = document.getElementsByTagName(\'input\')[0],
            showBox = document.getElementsByClassName(\'show-box\')[0];

        input.onchange = function () {
       var len = this.files.length; // 對于input上傳的圖檔,使用dom.files可以擷取圖檔資訊
            for(let i = 0; i < len; i++) {
                let fileImg = new FileReader();
                fileImg.readAsDataURL(this.files[i]); // readAsDataURL方法将圖檔轉為base64格式存儲于result中
                fileImg.onload = function() {
                    let oImg = new Image();
                    oImg.src = this.result; // 使用FileReader的result屬性擷取圖檔base64資訊
                    showBox.appendChild(oImg);
                }
          fileImg.onerror = function(e) {
            console.log(\'error\' + e);
          }
            }
        }
    </script>
</body>

</html>      

《四》FormData結合ajax将圖檔上傳至伺服器

知識點:FormData

FormData對象用以将資料編譯成鍵值對,以便用XMLHttpRequest來發送資料。

其主要用于發送表單資料,但也可用于發送鍵值對資料,獨立于表單使用,于是就有以下兩種方法:

1、不使用form表單,而使用鍵值對方式為FormData對象添加字段方式上傳檔案

方法:FormData.append()

// append()兩個重載函數
formData.append(name, value);
formData.append(name, value, filename); // filename可選
// 還有set()函數,它和append主要差別是:
// append 如果鍵已經存在,會将新值添加到已有的值集合後面
// set 如果鍵已經存在,會将新值覆寫原來的值      

value值可以是Blob或者Flie類型的值。

MDN中是這麼說的:

【方法】移動端H5如何調用相冊和相機上傳圖檔、音頻、視訊

其中Blob(binary large object),通俗講就是大的二進制對象,可以是圖檔、音頻,而且Blob常常是資料庫中用來存儲二進制檔案的字段類型,例如mysql資料庫。

再說回到第三個參數,隻有當value是blob或者file類型的時候,才可以添加第三個參數。當第二個參數為字元串時,會報錯:

【方法】移動端H5如何調用相冊和相機上傳圖檔、音頻、視訊

回到案例,上述例子中我們使用的就是沒有form表單的,是以我們基于《三》添加以下代碼:

// 我們建立一個FormData對象,然後每擷取一個檔案,就使用append()方法添加字段

var formData = new FormData();

// ...
fileImg.onload = function () {
   // ...
   formData.append(files[i].name, files[i]); // 鍵值對形式 此處append()第二個參數傳入的是檔案對象File類型
}

// 然後再使用ajax将formData資料傳送至伺服器

      

2、使用<form>表單初始化FormData對象方式上傳檔案

這裡我們使用jQuery來實作。

html代碼: 

// 使用form表單

<form id="uploadForm">
    <input id="file" type="file" name="file"/>
    <button id="upload" type="button">upload</button>
</form>      

js代碼:

var formData = new FormData($(\'#uploadForm\')[0]); // 注意:使用參數是一個DOM對象,而非jQuery對象;且必須是是form表單元素
// formData.append(\'num\', 1); // 也可以向已有表單的資料基礎上,繼續添加新的鍵值對
$.ajax({
    url: \'file.php\',
    type: \'POST\',
    data: formData,                    // 上傳formdata封裝的資料
    dataType: \'JSON\',
    cache: false,                      // 不緩存
    processData: false,                // jQuery不要去處理發送的資料
    contentType: false,                // jQuery不要去設定Content-Type請求頭
    success:function (data) {           //成功回調
        console.log(data);
    }
});
      

 在我們使用form表單初始化對象時,參數必須選擇form表單元素,否則就會報錯:

【方法】移動端H5如何調用相冊和相機上傳圖檔、音頻、視訊

【參考文章】

FormData對象的作用和用法、通過Ajax使用FormData對象無重新整理上傳檔案

利用FormData資料類型個php背景互動

《五》圖檔壓縮後再上傳伺服器

請轉至文章:如何實作圖檔壓縮并使用FormData上傳

【參考文章】

H5(移動端)前端使用input type=file上傳圖檔,調用相機和相冊

HTML5的input:file上傳類型控制

html5實作本地圖檔預覽功能