【转】文件各个上传,离不开的表单

by admin on 2018年12月24日

江湖已经这么不容易了,一定要找个能让您依靠和让你感觉舒适的胸怀。

表单异步上传(jquery.form插件)

固然下边的形式大概粗暴,不过不够团结。页面必然会刷新。难以实现停留在最近页面,并付诸文件上传成功的提拔。
趁着岁月的蹉跎,技术日新月异。ajax的出现,使得异步文件提交变得进一步便于。
上边大家拔取jquery.form插件来促成公文的异步上传。
率先我们需要导入jquery.jsjquery.form.js
前端代码:

<form id="form2" action="/Home/SaveFile2" method="post" enctype="multipart/form-data">
    <input type="file" class="file1" name="file1" />
    <button type="submit" class="but1">上传1</button>
    <button type="button" class="but2">上传2</button>
</form>

//方式2(通过ajaxForm绑定ajax操作)
$(function () {
    $('#form2').ajaxForm({
        success: function (responseText) {
            alert(responseText);
        }
    });
});

//方式3(通过ajaxSubmit直接执行ajax操作)
$(function () {
    $(".but2").click(function () {
        $('#form2').ajaxSubmit({
            success: function (responseText) {
                alert(responseText);
            }
        });
    });
});

后台代码:

public string SaveFile2()
{
    if (Request.Files.Count > 0)
    {                
        Request.Files[0].SaveAs(Server.MapPath("~/App_Data/") + Path.GetFileName(Request.Files[0].FileName));
        return "保存成功";
    }
    return "没有读到文件";
}

原理:
我们许多时候利用了插件,就随便其他三七二十一吧。
假设有点好奇心,想想这些插件是怎么落实的。随便看了看源码一千五百多行。我的妈啊,不就是个异步上传吗,怎么这么复杂。
难以见到个咋样鬼来,直接断点调试下吧。
必发365乐趣网投手机版 1
本来插件内部有iframe和FormData不同方法来上传,来适应更多版本浏览器。

因为阿鑫工作不稳定,在他老人家看来,他无法给小帆更好的前程。

上传插件(WebUploader)

一度列举分析了多种上传文件的法门,我想总有一种适合你。不过,上传这一个功用比较通用,而大家团结写的或许过多情状没有设想到。接下来简单介绍下百度的WebUploader插件。
比起我们自己写的简短上传,它的优势:稳定、兼容性好(有flash切换,所以协理IE)、效用多、并发上传、断点续传(紧要依旧靠后台配合)。
官网:http://fex.baidu.com/webuploader/
插件下载:https://github.com/fex-team/webuploader/releases/download/0.1.5/webuploader-0.1.5.zip
下边先导对WebUploader的应用
第一种,简单粗暴
前端代码:

<div id="picker">选择文件</div>
<button id="ctlBtn" class="btn btn-default">开始上传</button>

<!--引用webuploader的js和css-->
<link href="~/Scripts/webuploader-0.1.5/webuploader.css" rel="stylesheet" />
<script src="~/Scripts/webuploader-0.1.5/webuploader.js"></script>
<script type="text/javascript">
    var uploader = WebUploader.create({

        // (如果是新浏览器 可以不用 flash)
        //swf: '/Scripts/webuploader-0.1.5/Uploader.swf',

        // 文件接收服务端。
        server: '/Webuploader/SaveFile',

        // 选择文件的按钮。可选。
        // 内部根据当前运行是创建,可能是input元素,也可能是flash.
        pick: '#picker'
    });

    $("#ctlBtn").click(function () {
        uploader.upload();
    });

    uploader.on('uploadSuccess', function (file) {
        alert("上传成功");
    });

</script>

后台代码:

public string SaveFile()
{
    if (Request.Files.Count > 0)
    {
        Request.Files[0].SaveAs(Server.MapPath("~/App_Data/") + Path.GetFileName(Request.Files[0].FileName));
        return "保存成功";
    }
    return "没有读到文件";
}

其次种,分片上传。和我们后边自己写的效能差不多。
前者代码:

var uploader = WebUploader.create({ 
    //兼容老版本IE
    swf: '/Scripts/webuploader-0.1.5/Uploader.swf', 
    // 文件接收服务端。
    server: '/Webuploader/SveFile2', 
    // 开起分片上传。
    chunked: true, 
    //分片大小
    chunkSize: 1000000, 
    //上传并发数
    threads: 1,
    // 选择文件的按钮。 
    pick: '#picker'
});

// 点击触发上传
$("#ctlBtn").click(function () {
    uploader.upload();
});

uploader.on('uploadSuccess', function (file) {
    alert("上传成功");
});

后台代码:

public string SveFile2()
{
    //保存文件到根目录 App_Data + 获取文件名称和格式
    var filePath = Server.MapPath("~/App_Data/") + Path.GetFileName(Request.Files[0].FileName);
    //创建一个追加(FileMode.Append)方式的文件流
    using (FileStream fs = new FileStream(filePath, FileMode.Append, FileAccess.Write))
    {
        using (BinaryWriter bw = new BinaryWriter(fs))
        {
            //读取文件流
            BinaryReader br = new BinaryReader(Request.Files[0].InputStream);
            //将文件留转成字节数组
            byte[] bytes = br.ReadBytes((int)Request.Files[0].InputStream.Length);
            //将字节数组追加到文件
            bw.Write(bytes);
        }
    }
    return "保存成功";
}

我们看来了有个参数threads: 1上传并发数,假若我们改成大于1会怎么着?前端会同时提倡六个文件片上传。后台就会报错,三个过程同时操作一个文件。
这如果我们想要多线程上传怎么做?改代码吧(首尽管后台逻辑)。
前者代码:

//并发上传(多线程上传)
var uploader = WebUploader.create({
    //兼容老版本IE
    swf: '/Scripts/webuploader-0.1.5/Uploader.swf',
    // 文件接收服务端。
    server: '/Webuploader/SveFile3',
    // 开起分片上传。
    chunked: true,
    //分片大小
    chunkSize: 1000000,
    //上传并发数
    threads: 10,
    // 选择文件的按钮。
    pick: '#picker'
});

// 点击触发上传
$("#ctlBtn").click(function () {
    uploader.upload();
});

uploader.on('uploadSuccess', function (file) {
    //上传完成后,给后台发送一个合并文件的命令
    $.ajax({
        url: "/Webuploader/FileMerge",
        data: { "fileName": file.name },
        type: "post",
        success: function () {
            alert("上传成功");
        }
    });
});

后台代码:

public string SveFile3()
{
    var chunk = Request.Form["chunk"];//当前是第多少片 

    var path = Server.MapPath("~/App_Data/") + Path.GetFileNameWithoutExtension(Request.Files
    if (!Directory.Exists(path))//判断是否存在此路径,如果不存在则创建
    {
        Directory.CreateDirectory(path);
    }
    //保存文件到根目录 App_Data + 获取文件名称和格式
    var filePath = path + "/" + chunk;
    //创建一个追加(FileMode.Append)方式的文件流
    using (FileStream fs = new FileStream(filePath, FileMode.Append, FileAccess.Write))
    {
        using (BinaryWriter bw = new BinaryWriter(fs))
        {
            //读取文件流
            BinaryReader br = new BinaryReader(Request.Files[0].InputStream);
            //将文件留转成字节数组
            byte[] bytes = br.ReadBytes((int)Request.Files[0].InputStream.Length);
            //将字节数组追加到文件
            bw.Write(bytes);
        }
    }           
    return "保存成功";
}

/// <summary>
/// 合并文件
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public bool FileMerge()
{
    var fileName = Request.Form["fileName"];
    var path = Server.MapPath("~/App_Data/") + Path.GetFileNameWithoutExtension(fileName);

    //这里排序一定要正确,转成数字后排序(字符串会按1 10 11排序,默认10比2小)
    foreach (var filePath in Directory.GetFiles(path).OrderBy(t => int.Parse(Path.GetFileNameWithoutExtension(t))))
    {
        using (FileStream fs = new FileStream(Server.MapPath("~/App_Data/") + fileName, FileMode.Append, FileAccess.Write))
        {
            byte[] bytes = System.IO.File.ReadAllBytes(filePath);//读取文件到字节数组
            fs.Write(bytes, 0, bytes.Length);//写入文件
        }
        System.IO.File.Delete(filePath);
    }
    Directory.Delete(path);
    return true;
}

到这边你认为就得了了吧?错,还有好多气象并未考虑到。倘使四个用户上传的文件名字如出一辙会怎样?咋样贯彻断点续传?还没兑现选拔六个文本?然则,这里不打算继续贴代码了(再贴下去,代码量越来越多了),自己也来训练磨炼吧。
提供一个思路,上传前先往数据库插入一条数据。数据包含文件要存的路线、文件名(用GUID命名,防止同名文件争辩)、文件MD5(用来识别下次续传和秒传)、临时文件块存放路径、文件是否完好上传成功等消息。
下一场假若大家断网后再传,首先得到文件MD5值,看数据库里面有没上传完成的文本,倘若有就落实秒传。如果没有,看是不是有上传了有些的。假使有接着传,假诺没有则再度传一个新的文书。

而是,我和她在共同的时候,总是觉得少了点什么?

动用HTML5 拖拽、粘贴上传

不得不说H5真是强大啊,权限越来越大,操作更是牛逼。
前端代码(拖拽上传):

<textarea class="divFile7" style="min-width:800px;height:150px" placeholder="请将文件拖拽或直接粘贴到这里"></textarea>

//方式7
 $(".divFile7")[0].ondrop = function (event) {

     event.preventDefault();//不要执行与事件关联的默认动作
     var files = event.dataTransfer.files;//获取拖上来的文件

     //以下代码不变
     var formData = new FormData();//初始化一个FormData对象
     formData.append("files", files[0]);//将文件塞入FormData
     $.ajax({
         url: "/Home/SaveFile2",
         type: "POST",
         data: formData,
         processData: false,  // 告诉jQuery不要去处理发送的数据
         contentType: false,   // 告诉jQuery不要去设置Content-Type请求头
         success: function (responseText) {
             alert(responseText);
         }
     });
 };

后台代码:
略(和以前的SaveFile2一样)

前端代码(粘贴上传 限图片格式):

//方式8
$(".divFile7")[0].onpaste = function (event) {
    event.preventDefault();//不要执行与事件关联的默认动作
    var clipboard = event.clipboardData.items[0];//剪贴板数据
    if (clipboard.kind == 'file' || clipboard.type.indexOf('image') > -1) {//判断是图片格式
        var imageFile = clipboard.getAsFile();//获取文件

        //以下代码不变
        var formData = new FormData;
        formData.append('files', imageFile);
        formData.append('fileName', "temp.png");//这里给文件命个名(或者直接在后台保存的时候命名)
        $.ajax({
            url: "/Home/SaveFile8",
            type: "POST",
            data: formData,
            processData: false,  // 告诉jQuery不要去处理发送的数据
            contentType: false,   // 告诉jQuery不要去设置Content-Type请求头
            success: function (responseText) {
                alert(responseText);
            }
        });
    }
};

后台代码:

public string SaveFile8()
{
    //保存文件到根目录 App_Data + 获取文件名称和格式
    var filePath = Server.MapPath("~/App_Data/") + Request.Form["fileName"];      
    if (Request.Files.Count > 0)
    {
        Request.Files[0].SaveAs(filePath);
        return "保存成功";
    }
    return "没有读到文件";
}

效果图:
必发365乐趣网投手机版 2

在外面怎么着如何风光靓丽,是个女强人,然而在您面前,还是想要做个永远长不大的小公主,让你宠,让你哄。

分片上传

在理解了上边的各样上传之后,我们是不是就满于现状了呢?no,很多时候大家需要传输大文件,一般服务器都会有早晚的高低限制。
某天,你意识了一个豪情小电影想要分享个我们。无奈,高清文件太大传不了,如何做?我们可以化整为零,一部分局部的传嘛,也就是所谓的分片上传。
前者代码:

<input type="file" id="file6" multiple>
<button type="button" class="btnFile6">分片上传6</button>
<div class="result"></div>

//方式6
 $(".btnFile6").click(function () { 
     var upload = function (file, skip) {
         var formData = new FormData();//初始化一个FormData对象
         var blockSize = 1000000;//每块的大小
         var nextSize = Math.min((skip + 1) * blockSize, file.size);//读取到结束位置             
         var fileData = file.slice(skip * blockSize, nextSize);//截取 部分文件 块
         formData.append("file", fileData);//将 部分文件 塞入FormData
         formData.append("fileName", file.name);//保存文件名字
         $.ajax({
             url: "/Home/SaveFile6",
             type: "POST",
             data: formData,
             processData: false,  // 告诉jQuery不要去处理发送的数据
             contentType: false,   // 告诉jQuery不要去设置Content-Type请求头
             success: function (responseText) {
                 $(".result").html("已经上传了" + (skip + 1) + "块文件");
                 if (file.size <= nextSize) {//如果上传完成,则跳出继续上传
                     alert("上传完成");
                     return;
                 }
                 upload(file, ++skip);//递归调用
             }
         });
     };

     var file = $("#file6")[0].files[0];
     upload(file, 0);
 }); 

后台代码:

public string SaveFile6()
{
    //保存文件到根目录 App_Data + 获取文件名称和格式
    var filePath = Server.MapPath("~/App_Data/") + Request.Form["fileName"];
    //创建一个追加(FileMode.Append)方式的文件流
    using (FileStream fs = new FileStream(filePath, FileMode.Append, FileAccess.Write))
    {
        using (BinaryWriter bw = new BinaryWriter(fs))
        {
            //读取文件流
            BinaryReader br = new BinaryReader(Request.Files[0].InputStream);
            //将文件留转成字节数组
            byte[] bytes = br.ReadBytes((int)Request.Files[0].InputStream.Length);
            //将字节数组追加到文件
            bw.Write(bytes);
        }
    }
    return "保存成功";
}

相对而言,代码量多了少数,复杂了一点。可是相对于网上的其余分片上传的代码应该要简单得多(因为此处没有考虑多文本块同时上传、断点续传。这样就需要在后台把文件块排序,然后上传完成按序合并,然后删除原来的临时文件。有趣味的同桌可以团结尝试,稍候在条分缕析上传插件webuploader的时候也会促成)。
效果图:
必发365乐趣网投手机版 3
【表明】:假使我们想要上传五个公文咋办?其实H5中也提供了十分简单的措施。直接在input里面标记multiple<input type="file" id="file6" multiple>,然后大家后台接受的也是一个数组Request.Files

在对方眼里,你的这么些小动作仍然是讨人喜欢的一言一行。

总结

前边我一贯很迷惑,为啥上传文件一定要用form包起来,现在总算大概知道了。
最起头在javascript还不流行时,我们就足以一贯动用submit按钮提交表单数据了。表单里面可以分包文字和文书。然后随着js和ajax的流行,可以行使ajax直接异步提交部分表单数据。这里起首自我就纠结了,为何ajax可以交到自己组装的多寡。这为何无法直接提交文件呢。这里我错了,ajax提交的并不是自由的数目,最后如故组装成了表单格式(因为后台技术对表单格式数据的襄助相比较普及)。不过现有的技能还无法透过js组装一个文件格式的表单数据。直到H5中的FormData出现,让前端js组装一个暗含文件的表单格式数据变成了也许。所以说表单只是为了满意和后台“约定”的数码格式而已。

 

相关推荐

demo

 

那一个让您不爽快的人实则是与你的三观不相同。

【转】文件各类上传,离不开的表单

学妹雅儿近年来像自家吐口水,因为所有宿舍的人都在排斥她,她总是不在场集体活动。

使用表单实现公文上传

最原始、最简便易行、最粗暴的公文上传。
前端代码:

//方式1
<form action="/Home/SaveFile1" method="post" enctype="multipart/form-data">
     <input type="file" class="file1" name="file1" />
     <button type="submit" class="but1">上传</button>
</form>

【注意】

  • 1、需要post提交
  • 2、enctype=”multipart/form-data” (传输文件)
  • 3、需要交给的表单元素需要安装 name 属性

后台代码:

public ActionResult SaveFile1()
{
    if (Request.Files.Count > 0)
    {
        Request.Files[0].SaveAs(Server.MapPath("~/App_Data/") + Request.Files[0].FileName);
        return Content("保存成功");
    }
    return Content("没有读到文件");
}

但他依然假装一副很迎合的态度,插手到他们可以的商量中去。

用作程序员的我们,平日会要用到文件的上传和下载效率。到了特需用的时候,各种查资料。有木有..有木有…。为了便于下次接纳,这里来做个总括和备忘。

好的一方面都是面对旁人的,像那个所谓的礼貌、客套、坚强等。

模仿表单数据上传(FormData)

iframe这东西太恶心。大家看到地方可以采取FormData来上传文件,这么些是Html 5
才有的。上面咱们团结也来试试看把。
前者代码:

<input id="fileinfo" type="file" class="notFormFile" />
<button type="button" class="btnNotForm">上传4</button>

//方式4
$(".btnNotForm").click(function () {
    var formData = new FormData();//初始化一个FormData对象
    formData.append("files", $(".notFormFile")[0].files[0]);//将文件塞入FormData
    $.ajax({
        url: "/Home/SaveFile2",
        type: "POST",
        data: formData,
        processData: false,  // 告诉jQuery不要去处理发送的数据
        contentType: false,   // 告诉jQuery不要去设置Content-Type请求头
        success: function (responseText) {
            alert(responseText);
        }
    });
});

后的代码:(不变,依旧上例代码)

public string SaveFile2()
{
    if (Request.Files.Count > 0)
    {                
        Request.Files[0].SaveAs(Server.MapPath("~/App_Data/") + Path.GetFileName(Request.Files[0].FileName));
        return "保存成功";
    }
    return "没有读到文件";
}

咱俩看看,FormData对象也只是在模仿一个本来的表单格式的多少。那有没有可能不应用表单或表单格式来上传文件呢?答案是大势所趋的。(上边登时公布)
前端代码:

<input type="file"  id="file5" multiple>
<button type="button" class="btnFile5">上传5</button>    

//方式5
$(".btnFile5").click(function () {
    $.ajax({
        url: "/Home/SaveFile4",
        type: "POST",
        data: $("#file5")[0].files[0],
        processData: false,  // 告诉jQuery不要去处理发送的数据
        contentType: false,   // 告诉jQuery不要去设置Content-Type请求头
        success: function (responseText) {
            alert(responseText);
        }
    });;       
});       

后台代码:

public string SaveFile4()
{
    //这里发现只能得到一个网络流,没有其他信息了。(比如,文件大小、文件格式、文件名等)
    Request.SaveAs(Server.MapPath("~/App_Data/SaveFile4.data") + "", false);
    return "保存成功";
}

周详的你意识没有了表单格式,我们除了可以上传文件流数据外,不可以再告知后台其他音信了(如文件格式)。
到这边,我似乎知道了原先上传文件为啥非得要用个form包起来,原来这只是和后台约定的一个传输格式而已。
实质上我们仅仅的用jq的ajax传输文本数据的时候,最终也是组装成了form格式的数目,如:

 $.ajax({
    data: { "userName": "张三" } 

是一种很不佳受的痛感,在她眼前,我不可能一心做自己。

他又回升了原来的生存,和投机的伙伴,天天泡体育场馆,偶尔出去爬爬山。

室友们商量的影星是他不认得的,八卦的电视机剧是她没追过的,花痴的帅哥也是他不感兴趣的。

雅儿目前淡出了她们的集体,感觉就像是从牢笼里解放出的鸟儿一样,呼吸到干净的氛围,天高任鸟阔。

就像小帆和阿鑫一律,他们在一齐的时候,会很自在,很满意,很自在。

他对小帆呵护倍加,下班了就带她出去玩,公园、游戏场、滑冰场等等。

我会在阿鑫前边撒娇,无理取闹,任性妄为,说出自己的感触和想法,而不是像在他眼前一言不发。

在宿舍的姊妹们去外聚餐涮火锅的时候,她因为和爱人在外做权利劳动没有赶回去。

雅儿说,不是他不想和她俩在共同耍,只是她已经努力去融入她们的天地,但实际是兴趣不合,失利了。

不论是爱情如故友情,和何人舒服,就和谁在一齐。

06

每便去的地点都不雷同,变着法得哄小帆欣欣自得。

进食的时候,对方车接车送,小帆不用再挤公交受罪。

由此,你看不到她的微笑,她在熟人面前如脱兔般的模样。

稍许人,在旁人面前总是一副高冷的典范,其实不然,只是人家和您不熟而已。

03

如出一辙的,人家也不是专程掩饰,只是放不开而已。

文❤这何人菇凉

因为喜欢一个人,我们在他眼前不需要伪装,想哭就大声的哭,想笑就大声的笑,因为精晓对方不会在意。

不过交往了不到两个月,小帆依旧不曾爱上她,就指出了分手。

雅儿说,她刚开端的时候,也感觉自己很害羞,作为宿舍的一员,她总是缺席。

在您面前,即便自己在能死磕,境遇难过的坎,也会想要一头扑到您的怀里哭得像小孩,不要什么所谓的烈性。

在开宿舍下午团队睡衣大会,她因为一天的疲惫早已昏昏欲睡。

她说,这五回,不管家长在咋样阻隔,她都会坚决自己的选项。

图表发自与花瓣网

一次约会之后,小帆对他的回想不错。

他很好,帅气可爱,幽默诙谐,爱护温柔,是宏观伴侣的最佳人选。

由此,小帆决定和对方分手,和阿鑫复合。

不怕在她前头挖鼻孔,扣脚趾,也是一件毫无避讳的业务。

可是在阿鑫前面我却不是如此的。

而不是紧绷着神经,深怕自己做错了怎么样事,对方会高烧自己一样。

因此,圈子不同,不必强融。

必发365乐趣网投手机版,无戒365极限日更挑衅营 第69天

和让您不痛快的人在共同,就像是把您身处一个繁华的庙会,狂欢盛典,你却是孤独难耐。

在你眼里,大海很美,而在对方眼里,它淹死过许几个人。

02

因为他不敢想象,如果接纳嫁给这么些男人,这他的一世该是有多么苦痛。

只有最本真的一面是预留亲近的人。

咬牙了不到一星期,她就遗弃了。

小帆因为父母的拦截,和婚恋七年的阿鑫分别了。

就这么,一对相爱的爱侣被养父母棒打了鸳鸯。

理由就是,和她俩相处真的是太糟糕受了。

之所以,她想了挽救措施,就是知难而进拉进她们之间的离开。

在宿舍集体出来逛街买买买的时候,她和在集体活动时的同伴相约去爬山。

自我问他问哪些?

对方一表人才,有车有房,条件优厚,前途一片光明。

04

他说,也许人的年龄越来越大,我好像很难再爱上一个人。

01

好的爱恋相对是锦上添花的,好的友谊也是高山流水,相见恨晚的。

雅儿很拼命的想要和她们相处,然则在她们前边,她很累。

本身通晓小帆口中所说的这种痛感。

咱俩不需要去刻意逢迎,过于在乎对方的感触,强颜欢笑,弄得温馨身心疲惫。

05

因为,和您在一道,我是的确在做和好,不是假装很快乐。

任由爱情,仍然友情,和至极能让你感觉到舒服的人在同步。

平素不什么人对谁错,只是三观不一致一样而已。

他同意了老人家的部署,和亲近对象会合。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图