Ajax向后台傳入File類型參數


本文內容如下:

一. FormData簡介

二. Ajax使用FormData上傳文件

三. Ajax使用FormData上傳多個文件

四. Ajax使用FormData上傳文件綜合拓展

一. FormData簡介

 參考: https://segmentfault.com/a/1190000006716454

          https://www.cnblogs.com/jpfss/p/8960806.html

1. 概述

  FormData類型其實是在XMLHttpRequest 2級定義的,它是為序列化表以及創建與表單格式相同的數據(當然是用於XHR傳輸)提供便利。

2. 構造函數

創建一個formData對象實例有幾種方式

1、創建一個空對象實例

var formData = new FormData();

    此時可以調用append()方法來添加數據

 

2、使用已有的表單來初始化一個對象實例

假如現在頁面已經有一個表單

<form id="myForm" action="" method="post">
    <input type="text" name="name">名字
    <input type="password" name="psw">密碼
    <input type="submit" value="提交">
</form>

我們可以使用這個表單元素作為初始化參數,來實例化一個formData對象

// 獲取頁面已有的一個form表單
var form = document.getElementById("myForm");
// 用表單來初始化
var formData = new FormData(form);
// 我們可以根據name來訪問表單中的字段
var name = formData.get("name"); // 獲取名字
var psw = formData.get("psw"); // 獲取密碼
// 當然也可以在此基礎上,添加其他數據 formData.append("token","kshdfiwi3rh");

注: 通過 FormData.append()方法賦給字段的值若是數字會被自動轉換為字符(字段的值可以是一個Blob對象,一個File對象,或者一個字符串,剩下其他類型的值都會被自動轉換成字符串).

3. 操作方法

首先,我們要明確formData里面存儲的數據形式,一對key/value組成一條數據,key是唯一的,一個key可能對應多個value。如果是使用表單初始化,每一個表單字段對應一條數據,它們的HTML name屬性即為key值,它們value屬性對應value值。

key value
k1 [v1,v2,v3]
k2 v4

3.1 獲取值

我們可以通過get(key)/getAll(key)來獲取對應的value

formData.get("name"); // 獲取key為name的第一個值
formData.getAll("name"); // 返回一個數組,獲取key為name的所有值

3.2 添加數據

我們可以通過append(key, value)來添加數據,如果指定的key不存在則會新增一條數據,如果key存在,則添加到數據的末尾

formData.append("k1", "v1");
formData.append("k1", "v2");
formData.append("k1", "v1");

formData.get("k1"); // "v1"
formData.getAll("k1"); // ["v1","v2","v1"]

3.3 設置修改數據

我們可以通過set(key, value)來設置修改數據,如果指定的key不存在則會新增一條,如果存在,則會修改對應的value值。

formData.append("k1", "v1");
formData.set("k1", "1");
formData.getAll("k1"); // ["1"]
 

3.4 判斷是否該數據

               有的瀏覽器未實現has()的方式,使用時需注意

我們可以通過has(key)來判斷是否對應的key值

formData.append("k1", "v1");
formData.append("k2",null);

formData.has("k1"); // true
formData.has("k2"); // true
formData.has("k3"); // false

3.5 刪除數據

通過delete(key),來刪除數據

formData.append("k1", "v1");
formData.append("k1", "v2");
formData.append("k1", "v1");
formData.delete("k1");

formData.getAll("k1"); // []

3.6 遍歷

我們可以通過entries()來獲取一個迭代器,然后遍歷所有的數據,

formData.append("k1", "v1");
formData.append("k1", "v2");
formData.append("k2", "v1");

var i = formData.entries();

i.next(); // {done:false, value:["k1", "v1"]}
i.next(); // {done:false, value:["k1", "v2"]}
i.next(); // {done:false, value:["k2", "v1"]}
i.next(); // {done:true, value:undefined}

可以看到返回迭代器的規則

    1. 每調用一次next()返回一條數據,數據的順序由添加的順序決定

    2. 返回的是一個對象,當其done屬性為true時,說明已經遍歷完所有的數據,這個也可以作為判斷的依據

    3. 返回的對象的value屬性以數組形式存儲了一對key/value,數組下標0為key,下標1為value,如果一個key值對應多個value,會變成多對key/value返回

我們也可以通過values()方法只獲取value值

formData.append("k1", "v1");
formData.append("k1", "v2");
formData.append("k2", "v1");

var i = formData.values();

i.next(); // {done:false, value:"v1"}
i.next(); // {done:fase, value:"v2"}
i.next(); // {done:fase, value:"v1"}
i.next(); // {done:true, value:undefined}

4. 發送數據

我們可以通過xhr來發送數據

var xhr = new XMLHttpRequest();
xhr.open("post","login");
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.send(formData);

這種方式可以來實現文件的異步上傳。

 

二. Ajax使用FormData上傳文件

1.使用<form>表單初始化FormData對象方式上傳文件

HTML代碼:

<form id="uploadForm" enctype="multipart/form-data">
    <input id="file" type="file" name="file"/>
    <button id="upload" type="button">upload</button>
</form>

javascript代碼

        $("#upload").click(function () {
            $.ajax({
                url: '/Default/UploadFile',
                type: 'POST',
                cache: false,
                data: new FormData($('#uploadForm')[0]),
                processData: false,
               contentType: false,
                success: function (data) {
                    alert(data.result)
                }
            }).fail(function (res) {
                alert("系統錯誤")
            });
        });


這里要注意幾點:

    • processData設置為false。因為data值是FormData對象,不需要對數據做處理。
    • <form>標簽添加enctype="multipart/form-data"屬性。
    • cache設置為false,上傳文件不需要緩存。
    • contentType設置為false,不設置contentType值,因為是由<form>表單構造的FormData對象,且已經聲明了屬性enctype="multipart/form-data",所以這里設置為false。

          上傳后,服務器端代碼需要使用從查詢參數名為file獲取文件輸入流對象,因為<input>中聲明的是name="file"

后台代碼:

        [HttpGet]
        public IActionResult UploadFile()
        {
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> UploadFile(IFormFile file)
        {
            string oFileName = Path.GetFileName(file.FileName);
            if (!string.IsNullOrEmpty(oFileName))
            {
                return Json(new
                {
                    Result = "Success",
                    Message = ""
                });
            }
            return Json(new
            {
                Result = "Failed",
                Message = ""
            });
        }

2.使用FormData對象添加字段方式上傳文件

HTML代碼:

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

javascript代碼

        $("#upload").click(function () {
            var formData = new FormData();
            formData.append('file', $('#file')[0].files[0]);
            $.ajax({
                url: '/Default/UploadFileByFormData',
                type: 'POST',
                cache: false,
                data: formData,
                processData: false,
               contentType: false,
                success: function (data) {
                    alert(data.result)
                }
            }).fail(function (res) {
                alert("系統錯誤")
            });
        });

這里有幾處不一樣:

    • append()的第二個參數應是文件對象,即$('#file')[0].files[0]
    • contentType也要設置為‘false’。

從代碼$('#file')[0].files[0]中可以看到一個<input type="file">標簽能夠上傳多個文件,
只需要在<input type="file">里添加multiplemultiple="multiple"屬性。

后台代碼

        public async Task<IActionResult> UploadFileByFormData(IFormFile file)
        {
            string oFileName = Path.GetFileName(file.FileName);
            if (!string.IsNullOrEmpty(oFileName))
            {
                return Json(new
                {
                    Result = "Success",
                    Message = ""
                });
            }
            return Json(new
            {
                Result = "Failed",
                Message = ""
            });
        }

 

三. Ajax使用FormData上傳多個文件

<input type="file">里添加multiple="multiple"屬性,選擇文件時,按住Ctrl鍵或Shift鍵選擇多個文件

HTML代碼

    <div id="uploadForm">
        <input id="file" type="file" multiple="multiple" />
        <button id="upload" type="button">upload</button>
    </div>

javascript代碼

    <script type="text/javascript">
        $("#upload").click(function () {
            var formData = new FormData();
          for (var i = 0; i < $('#file')[0].files.length; i++) {
                formData.append('files', $('#file')[0].files[i]);
            }
            $.ajax({
                url: '/Default/UploadFilesByFormData',
                type: 'POST',
                cache: false,
                data: formData,
                processData: false,
                contentType: false,
                success: function (data) {
                    alert(data.message)
                }
            }).fail(function (res) {
                alert("系統錯誤")
            });
        });
    </script>

后台代碼

      public async Task<IActionResult> UploadFilesByFormData(IFormFile[] files)
        {
            string fileNames = "";
            for (int i = 0; i < files.Length; i++)
            {
                fileNames += files[i].FileName+"; ";
            }

            return Json(new
            {
                Result = "Success",
                Message = fileNames
            });
        }

 

四. Ajax使用FormData上傳文件綜合拓展

  通過在<input type="file">里添加multiple="multiple"屬性,雖然能夠實現一次長傳多個文件,但是並不能顯示多個文件的文件名,也不能對選中的文件進行刪除,新增的操作,以下實例是優化后的多個文件上傳。

  實現效果如下:

  

 HTML代碼:

    <table>
        <tr style="width:100%;">
            <td style="width:150px; text-align:right;line-height:40px;"><label style="margin-top:8px;">附件上傳:</label></td>
            <td colspan="3" style="margin-left:50px;text-align:left;line-height:40px;">
                <img src="~/images/附件.png" style="height:10%" />&nbsp;
                <input id="file" type="file" style="display:none;" onchange="AddFile()" />
                <span id="sfile" onclick="document.getElementById('file').click()" style="line-height:40px;color:gray;font-weight:600;"> Add  File</span>
            </td>
        </tr>
    </table>
    <div id="divShowFile">

    </div>
    <button id="upload" type="button" style="margin-left:150px;">upload</button>
<style type="text/css"> #sfile:hover { text-decoration: underline; cursor: pointer; color: blue; } </style>

javascript代碼

<script type="text/javascript">
        var FileData = new FormData();//保存File文件
        var num = 0;//保存file文件id序號
        function AddFile() {
            var isonly = "T";
            var fileid = "file" + num;
            var pid = "p" + num;
            var lblid = "lbl" + num;
            var filePath = $('#file').val();
            if (filePath.trim() != "") {//選擇了上傳文件
                //遍歷FileData,看是否有重復數據
                $(".lblfile").each(function () {
                    if (filePath == $(this).text()) {
                        isonly = "F";
                        alert("File has upload");
                    }
                });
                if (isonly == "T") {
                    //將上傳的文件添加到全局變量FileData中
                    FileData.append(fileid, $('#file')[0].files[0]);

                    //添加P標簽,顯示上傳文件名
                    var p = "<p id=" + pid + " style='margin-left:140px;'> <label class='lblfile' id=" + lblid + " Title=" + fileid + ">" + filePath + "</label>  &nbsp;";
                    p += "<img src='/images/刪除.png' style='width:1%;cursor:pointer;' onclick='DeleteFile(\"" + fileid + "\",\"" + pid + "\")'>";
                    p += "</p>";
                    $("#divShowFile").append(p);
                    num++;
                }
            }
        }

        function DeleteFile(fileid, pid) {
            //將刪除的文件從全局變量FileData中刪除
            FileData.delete(fileid);
            //刪除對應的P標簽
            $("#" + pid).empty();
        }

        $("#upload").click(function () {
            debugger;
            if ($(".lblfile").length == 0) {
                alert("請加入上傳文件");
            }
            var formData = new FormData();
            $(".lblfile").each(function () {
                formData.append("files", FileData.get($(this)[0].title));
            });
            $.ajax({
                url: '/File/UploadFiles',
                type: 'POST',
                cache: false,
                data: formData,
                processData: false,
                contentType: false,
                success: function (data) {
                    alert(data.result)
                }
            }).fail(function (res) {
                alert("系統錯誤")
            });
        });
    </script>

后台代碼:

此處是將上傳的批量File文件保存到Azure Blob,上傳文件到Azure Blob可以看我之前寫的博客 https://www.cnblogs.com/suflowers1700218/p/13606425.html

        #region[文件上傳]
        public IActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> UploadFiles(IFormFile[] files)
        {
            try
            {
                for (int i = 0; i < files.Length; i++)
                {
//上傳文件到Azure Blob
string oFileName = Path.GetFileName(files[i].FileName);//獲取文件名 string fileExtension = Path.GetExtension(oFileName).ToLower();//獲取文件擴展名 string AzureFilePath = $"{DateTime.Now.ToString("yyyyMMddHHmmssfff")}" + fileExtension; await AzureHelp.FileUploadAsync(AzureFilePath, files[i].OpenReadStream(), StorageConnectionstring, ContainerName); } return Json(new { Result = "Success", Message = "" }); } catch (Exception ex) { return Json(new { Result = "Failed", Message = ex.Message }); } } #endregion

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM