第十五 文件上传

今天没事帮小凸,做一个需求,文件上传 ,好久没有写这些东西了,那些控件什么的也不想用,就想着自己写一个吧 ,简单的 ,本来上传的原理也就那样,很多控件只是封装了很多功能,但是核心的东西也就那么点,今天就记录一下,
第一种,纯js文件上传,后台C#接收
     <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
 
 
 
<!DOCTYPE html>
 
 
 
<html>
 
<head runat="server">
 
    <meta name="viewport" content="width=device-width" />
 
    <title>Index</title>
 
</head>
 
<body>
 
    <form id="form1" runat="server">
 
        <p>
 
            上传文件:
 
            <input id="updatefile" type="file" /><br />
 
 
 
        </p>
 
        <input  type="button" id="sendfile" onclick="senddata()" value="提交数据" />
 
    </form>
 
    <script type="text/javascript">
 
        function senddata() {
 
            //拿到你要上传的文件
 
            var fileupload = document.getElementById('updatefile').files;
 
            //这个是发送的数据,键值对,原生js发送数据就是使用的这个
 
            var formdata = new FormData();
 
            formdata.append('files', fileupload[0]);
 
            //创建一个请求对象,这个不同的浏览器有所不同,这里就不做判断了 ,这个是很多浏览器支持的(除了IE),
 
            var xmlHttp = new XMLHttpRequest();
 
            //打开链接
 
            xmlHttp.open("post", '/home/UpdateFileData');
 
            //监听返回状态
 
            xmlHttp.onreadystatechange = function (zdata) {
 
                if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
 
                    alert(zdata.currentTarget.responseText);
 
                    console.log(zdata.currentTarget.responseText)
 
                }
 
            }
 
            //上传进度条在这里做 ,evt里面返回的用数据
 
            //xmlHttp.upload.onprogress = function (evt) { };
 
 
 
            //发送数据
 
            xmlHttp.send(formdata);
 
        }
 
    </script>
 
</body>
 
 
 
 
 
</html>
 
后台代码就简单了
/// <summary>
 
        /// 第一种实现
 
        /// </summary>
 
        /// <returns></returns>
 
        [HttpPost]
 
        public string UpdateFileData()
 
        {
 
 
 
          
 
            HttpFileCollectionBase file = HttpContext.Request.Files; 
 
           
 
            file[0].SaveAs(@"D:\net_test\" + file[0].FileName);
 
            return "zzl";
 
        }
--
 
第二种  jq的 Ajax和C#接收
   
 
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
 
 
 
<!DOCTYPE html>
 
 
 
<html>
 
<head runat="server">
 
    <meta name="viewport" content="width=device-width" />
 
    <title>FileUpdateone</title>
 
</head>
 
<body>
 
    <di>
 
       
 
    </di>    <form id="form1" runat="server">
 
        <p>
 
            上传文件:
 
            <input id="updatefile" type="file" /><br />
 
 
 
        </p>
 
        <input  type="button" onclick="sendfile()" value="提交数据" />
 
    </form>
 
    <script src="../../Scripts/jquery-1.8.2.min.js"></script>
 
    <script type="text/javascript">
 
        function sendfile() {
 
            //同样的获取上传文件
 
            var file = document.getElementById("updatefile").files[0];
 
            var formdata = new FormData();
 
            formdata.append("file", file);
 
            formdata.append("zzlfile", "zzl");
 
            $.ajax({
 
                type: "POST",
 
                url: "/home/FileUpdateoneGet",
 
                data: formdata,
 
                processData: false,   //不做数据转化
 
                contentType: false,   //不改变数据请求类型
 
                success:function(data){
 
                    alert(data);
 
                },
 
                error:function(error){
 
                }
 
            })
 
 
 
        }
 
    </script>
 
</body>
 
</html>
 
后台接收和上面的一样
 
        /// <summary>
 
        /// 第二种实现
 
        /// </summary>
 
        /// <returns></returns>
 
        public string FileUpdateoneGet()
 
        {
 
         
 
 
 
 
 
 
 
 
 
          
 
            var file = Request.Files;
 
           
 
          
 
            file[0].SaveAs(@"D:\net_test\zzl\" + i + "_" + file[0].FileName);
 
          
 
            return "autohome";
 
        }
这里需要注意的两个 :
   第一个是:processData这个要设置成false,不让对数据做处理
    第二个是:contentType,不让对请求头类型做改变,
如果我们要上传文件,或者是文件和其他key-val键值对的时候,我们的Content-Type的类型必须是: 
 
multipart/form-data,不然数据发送不到后台,
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryahxAneFgTBBt9Vz5
Content-Type:的两部分,第一部分是请求头的类型,第二部分,是分割数据的标识,必经我们可能有很多数据上传

 
 
x-www-form-urlencoded:这种是POST提交数据这种是所有键值对的数据,推荐的数据是编码的
multipart/form-data:这种是POST数据中含有文件,(可以是只有文件,或者是文件和key-val都有),
 
最后给大家一个图片下载的流程:也是一个简单的操作,拿到流,处理流,写入流
public void Dowland()
 
        {
 
            //声明一个随机数,(用GUID做一个种子,防止多线程,大请求的时候随机数一样)
 
            //Random在高并发微妙级别的情况下是会重复的
 
            Random rnd = new Random(Guid.NewGuid().GetHashCode());
 
            int i = rnd.Next();
 
 
 
 
            //获取请求的相应
 
            WebResponse response = request.GetResponse();
 
            //取得响应流
 
            Stream reader = response.GetResponseStream();
 
            //创建一个写入流
 
            FileStream writer = new FileStream(@"D:\net_test\zzl\" + i + "_.jpg",FileMode.OpenOrCreate, FileAccess.Write);
 
            //创建一个字节数组
 
            byte[] buff = new byte[512];
 
            int c = 0; //实际读取的字节数
 
            while ((c = reader.Read(buff, 0, buff.Length)) > 0)
 
            {
 
                //读取写入,c为每次读取了多少字节的数据,千万不能使用 buff.Length,因为reader的数据不一定是 buff.Length的整数倍,
 
                //如果使用buff.Length会造成写入的文件不能使用
 
                writer.Write(buff, 0, c);
 
            }
 
            //关闭写入流,和释放写入流,这个也是必须的,
 
            writer.Close();
 
            writer.Dispose();
 
            //释放响应流
 
            reader.Close();
 
        }
 
posted @ 2019-10-21 14:41  瀚海行舟  阅读(118)  评论(0编辑  收藏  举报