第十五 文件上传
今天没事帮小凸,做一个需求,文件上传 ,好久没有写这些东西了,那些控件什么的也不想用,就想着自己写一个吧 ,简单的 ,本来上传的原理也就那样,很多控件只是封装了很多功能,但是核心的东西也就那么点,今天就记录一下,
第一种,纯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();
WebRequest request = WebRequest.Create("http://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1571378083685&di=46f0cd5a97fadf6c919bcfaa3f1dfddf&imgtype=0&src=http%3A%2F%2Fimg8.zol.com.cn%2Fbbs%2Fupload%2F18863%2F18862812.JPG");
//获取请求的相应
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();
}