JavaScript FormData對象,FileReader對象,files屬性

一.ajax與FormData的使用

  最近在使用ajax朝後端提交數據時,若是提交的數據都是普通鍵值對還好說,直接使用ajax默認的格式向後端提交便可。css

$('#d1').click(function () {
        $.ajax({
            // 提交的地址,不寫默認提交至當前頁面,同form表單的action
            url:'/index/',
            // 提交的方式
            type:'post',
            // 提交的數據,通常以鍵值對的形式出現
            data:{'name':'jason','password':'123'},
            // 回調函數
            success:function (data) {  // data接收的就是異步提交返回的結果
                alert(data)
            }
        })
    })

   可是當有form表單中有提交文件的input框時<input type="file"  id='my_file'>,就必須使用JS的files屬性以及修改ajax的編碼格式了。除此以外還要使用FormData對象,它不只能夠存普通鍵值對,還能夠存文件。html

  $('#b1').on('click', function () {
      let formdata = new FormData();//生成一個FormData對象
      //$('#f1')[0]獲得的是JQuery對象中的第一個JS對象,JS_obj.files拿到的包含全部文件對象的數組,經過索引取第一個文件對象
     //能夠將formdata想象成一個字典或者說是自定義對象,執行append('key', 'value')給字典添加鍵值對
      formdata.append('file', $('#f1')[0].files[0]);
      $.ajax({
          url:'',
          type:'post',
          contentType:false,//用FormData自帶的編碼,因此不須要設置contentType
          processData:false,//告訴瀏覽器不要處理數據
          data: formdata,//直接將formdata提交至後端便可,後端request.POST拿到的是其中的普通鍵值對,而request.FILES拿到的就是其中的文件鍵值對
          success:function (data) {
              alert(data)
          }
      })
  })

 二. FileReader對象的使用

  在寫一個註冊頁面時,想要實現用戶選擇頭像時,直接就能將選擇的頭像顯示出來,就必須使用到JS的FileReader對象。前端

  FileReader 對象容許Web應用程序異步讀取存儲在用戶計算機上的文件(或原始數據緩衝區)的內容,使用 File 或 Blob 對象指定要讀取的文件或數據。 jquery

  其中File對象能夠是來自用戶在一個元素上選擇文件後返回的FileList對象(上面提到的使用files屬性獲得的文件對象),也能夠來自拖放操做生成的 DataTransfer對象,還能夠是來自在一個HTMLCanvasElement上執行mozGetAsFile()方法後返回結果
web

  2.1 能夠用window對象的方法查看瀏覽器對FileReader的支持ajax

if(window.FileReader) {
     var fr = new FileReader();
     // add your code here
 }
 else {
     alert("Not supported by your browser!");
 }

  2.2 將上傳頭像顯示出來的前端代碼實現bootstrap

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>register</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<!--用bootstrap渲染過的頁面,這裏爲了方便只寫了一個上傳頭像的input框-->
<div class="container">
    <div class="row">
        <div class="col-md-5 col-md-offset-3">
            <h2 class="text-center">註冊</h2>
            <div>
                <!--將img標籤用label 標籤包了起來,而後用display將Input框隱藏,這樣點擊圖片就能選擇上傳頭像-->
                <label for="my_file">頭像<img id='id_img' src="/static/img/111.jpg" alt="" style="width: 80px"> </label>
            </div>
            <input type="file" name='myfile' id="my_file" style="display: none">
        </div>
    </div>
</div>
<script>
    /*給input框綁定change事件,內容改變就會觸發,因此當選擇頭像而後上傳時觸發*/
    $('#my_file').change(function () {
        /*利用JS的files屬性獲得一個自定義對象(字典),鍵0對應的值就是文件對象,實際上就是咱們上傳的頭像*/
        let fileObj = this.files[0];
        /*生成JS的FileReader對象*/
        let fileReader = new FileReader();
        /*將上傳的頭像交予fileReader對象,讓其將內容讀取而後渲染出來*/
        fileReader.readAsDataURL(fileObj);
        /*給fileReader對象綁定事件,等渲染完成後再執行function中的代碼*/
        fileReader.onload = function () {
            /*將img標籤中的src屬性換成fileReader渲染過的內容,即換成咱們上傳的頭像*/
            $('#id_img').attr('src', fileReader.result)
        }
    })
</script>
</body>
</html>

  files屬性獲得的自定義對象:後端

  2.3 FileReader對象的方法數組

  readAsText該方法有兩個參數,其中第二個參數是文本的編碼方式,默認值爲 UTF-8。這個方法很是容易理解,將文件以文本方式讀取,讀取的結果便是這個文本文件中的內容。
  readAsBinaryString該方法將文件讀取爲二進制字符串,一般咱們將它傳送到後端,後端能夠經過這段字符串存儲文件。
  readAsDataURL這是例子程序中用到的方法,該方法將文件讀取爲一段以 data: 開頭的字符串,這段字符串的實質就是 Data URL,Data URL是一種將小文件直接嵌入文檔的方案。這裏的小文件一般是指圖像與 html 等格式的文件。(其中base64的方式就是由此來得到的。。)瀏覽器

   2.4 FileReader包含的事件

   例子中使用了fileReader的.onload事件,當fileReader對象的方法執行完畢時就會執行onload後面指定的function,若是不使用onload,例子是不可能成功的,你會發現一上傳頭像,對應的Img原來的圖片也會沒有了。由於img要的是fileReader.result的結果,但是fileReader讀取以及渲染文件須要時間,它又是異步的,因此img的到的結果是空,而不是咱們上傳的頭像。

  

  只要文件開始讀取,不管結果若是,FileReader的對象中result屬性都會有值,成功了就是讀取的結果,失敗了就是None。

  是否疑惑以前img標籤的src屬性咱們放的都是路徑,但是fileReader.result拿出來的確定不是路徑啊,爲何當作src屬性的值時能夠顯示出來?這是由於img標籤的src屬性不只支持文件路徑,還支持文件二進制數據或者url。

三. window.createObjectURL獲取文件路徑

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>register</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<!--用bootstrap渲染過的頁面,這裏爲了方便只寫了一個上傳頭像的input框-->
<div class="container">
    <div class="row">
        <div class="col-md-5 col-md-offset-3">
            <h2 class="text-center">註冊</h2>
            <div>
                <!--將img標籤用label 標籤包了起來,而後用display將Input框隱藏,這樣點擊圖片就能選擇上傳頭像-->
                <label for="my_file">頭像<img id='id_img' src="/static/img/111.jpg" alt="" style="width: 80px"> </label>
            </div>
            <input type="file" name='myfile' id="my_file" style="display: none">
        </div>
    </div>
</div>
<script>
    $("#my_file").change(function(){
  var objUrl = getObjectURL(this.files[0]) ;
  console.log("objUrl = "+objUrl) ;
  if (objUrl) {
    $("#id_img").attr("src", objUrl) ;
  }
}) ;

//取得該文件的url
function getObjectURL(file) {
  var url = null ;
  if (window.createObjectURL!=undefined) {
    url = window.createObjectURL(file) ;
  } else if (window.URL!=undefined) {
    url = window.URL.createObjectURL(file) ;
  } else if (window.webkitURL!=undefined) {
    url = window.webkitURL.createObjectURL(file) ;
  }
  return url ;
}
</script>
</body>
</html>
相關文章
相關標籤/搜索