1. 程式人生 > >js 實現檔案上傳

js 實現檔案上傳

一、利用 FormData 物件形式上傳

       FormData 是 XMLHttpRequest 2 的產物,相容 IE10+。

       FormData 物件,可以把form中所有表單元素的name與value組成一個queryString,提交到後臺。在使用Ajax提交時,使用FormData物件可以減少拼接queryString的工作量。

       使用 FormData 物件

       1.取得form物件,作為引數傳入到FormData物件

//html
<form name="form1" id="form1">  
     <input type="text" name="name" value="fdipzone">  
     <input type="text" name="gender" value="male">  
</form>  

//js
var form = document.getElementById('form1');  
var formdata = new FormData(form);  

       2.建立一個FormData空物件,然後使用append方法新增key/value

var formdata = new FormData();  
formdata.append('name','fdipzone');  
formdata.append('gender','male');  

       使用FormData提交表單及上傳檔案例項:

例項1

    一般專案中使用的點選上傳檔案的按鈕跟 <input type="file"/> 預設樣式是不一樣的,我們得自定義。方法是,自己寫一個<button> 按鈕,然後再寫一個 <input type="file"/>(這個要隱藏,太難看),點選 <button> 的時候出發 <input type="file"/> 的 click 事件。

HTML:

<input type="file"  
       :style="{display: 'none'}"  
       ref="input" @change="selectedFile"
/>  
<button @click="upload">上傳</button>  

JS:

methods: {  
    triggerSelect () {  
      this.$refs.input.click()  
    },  
  
    selectedFile (e) {  
      console.log(e.target.files[0])  
      //根據專案需求做具體處理,比如說獲取檔名  
    },  
  
    async upload () {  
      //如果不需要用到上傳後的返回值可以把 async...await 語法去掉  
      let files = this.$refs.input.files;  
      if(files.length > 0) {  
        let form = new FormData();  
        form.append('file', files[0])  
        let data = await new Promise((resolve, reject) => {  
            axios({  
              url: '',  
              method: 'post',  
              data: form  
            })  
              .then(res => {  
                resolve(res)  
              })  
              .catch(err => {  
                reject(err)  
              })  
          })  
      }  
    }  
}  

例項2

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">  
<html>  
 <head>  
  <meta http-equiv="content-type" content="text/html; charset=utf-8">  
  <title> FormData Demo </title>
 </head>  
 <body>  
    <form name="form1" id="form1">  
        <p>name:<input type="text" name="name" ></p>  
        <p>gender:<input type="radio" name="gender" value="1">male <input type="radio" name="gender" value="2">female</p>  
        <p>photo:<input type="file" name="photo" id="photo"></p>  
        <p><input type="button" name="b1" value="submit" onclick="fsubmit()"></p>  
    </form>  
    <div id="result"></div>  
    
  <script src="//code.jquery.com/jquery-1.11.0.min.js"></script>  
  <script type="text/javascript">  
    function fsubmit(){  
        var data = new FormData($('#form1')[0]);  
        $.ajax({  
            url: 'server.php',  
            type: 'POST',  
            data: data,  
            dataType: 'JSON',  
            cache: false,  
            processData: false,  //不處理髮送的資料,因為data值是FormData物件,不需要對資料做處理 
            contentType: false   //不設定Content-type請求頭
        }).done(function(ret){  
            if(ret['isSuccess']){  
                var result = '';  
                result += 'name=' + ret['name'] + '<br>';  
                result += 'gender=' + ret['gender'] + '<br>';  
                result += '<img src="' + ret['photo']  + '" width="100">';  
                $('#result').html(result);  
            }else{  
                alert('提交失敗');  
            }  
        });  
        return false;  
    }  
  </script>  
</body>  
</html>  

         server.php

<?php  
$name = isset($_POST['name'])? $_POST['name'] : '';  
$gender = isset($_POST['gender'])? $_POST['gender'] : '';  
  
$filename = time().substr($_FILES['photo']['name'], strrpos($_FILES['photo']['name'],'.'));  
  
$response = array();  
  
if(move_uploaded_file($_FILES['photo']['tmp_name'], $filename)){  
    $response['isSuccess'] = true;  
    $response['name'] = $name;  
    $response['gender'] = $gender;  
    $response['photo'] = $filename;  
}else{  
    $response['isSuccess'] = false;  
}  
  
echo json_encode($response);  
?>  

      帶顯示圖片的上傳圖片

    // -------- 將以base64的圖片url資料轉換為Blob --------
    function convertBase64UrlToBlob(urlData, filetype){
        //去掉url的頭,並轉換為byte
        var bytes = window.atob(urlData.split(',')[1]);
        
        //處理異常,將ascii碼小於0的轉換為大於0
        var ab = new ArrayBuffer(bytes.length);
        var ia = new Uint8Array(ab);
        var i;
        for (i = 0; i < bytes.length; i++) {
            ia[i] = bytes.charCodeAt(i);
        }

        return new Blob([ab], {type : filetype});
    }
    
    $input.on('change', function (e) {
        var input = $input.get(0);
        var files = input.files || [];
        if (files.length === 0) {
            return;
        }

        console.log('選中 ' + files.length + ' 個檔案');

        // 遍歷選中的檔案,預覽、上傳
        $.each(files, function (key, file) {
            var filename = file.name || '';
            var fileType = file.type || '';
            
            var reader = new FileReader();
            // onload事件
            reader.onload = function (e) {
                var base64 = e.target.result || this.result;
                var formData = new FormData();
                
                formData.append("upload_file", convertBase64UrlToBlob(base64, fileType), filename);
                var xhr = new XMLHttpRequest();
                // 開始上傳
                xhr.open('POST', uploadImgUrl, true);
                
                // 傳送資料
                xhr.send(formData);
            });
            
            reader.readAsDataURL(file);
        });
	});

二、base64 字串方式上傳圖片

       base64 線上轉換網站:http://tool.css-js.com/base64.html

       DataURI 允許在HTML文件中嵌入小檔案,可以使用 img 標籤或 CSS 嵌入轉換後的 Base64 編碼,減少 HTTP 請求,加快小影象的載入時間。 經過Base64 編碼後的檔案體積一般比原始檔大 30% 左右。

// Base64 在CSS中的使用
.box{
  background-image: url("data:image/jpg;base64,/9j/4QMZR...");
}
// Base64 在HTML中的使用
<img src="data:image/jpg;base64,/9j/4QMZR..." />

(不推薦用base64,效率慢,消耗流量,佔用空間。推薦使用把base64圖片格式轉換成FormData形式傳遞)