zoukankan      html  css  js  c++  java
  • 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值。

    keyvalue
    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="100%;">
                <td style="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='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
  • 相关阅读:
    元素模式
    完美C++(第5版)(双色)
    ASP.NET Web API 2框架揭秘
    跨终端 Web
    WebKit技术内幕
    云计算时代——本质、技术、创新、战略
    互联网创业密码
    Netty权威指南
    Robot Framework 学习笔记(二)-------第一个脚本
    Robot Framework学习笔记(一)------环境搭建
  • 原文地址:https://www.cnblogs.com/suflowers1700218/p/14230852.html
Copyright © 2011-2022 走看看