记得以前老师教我们写项目,要实现图片上传的功能,我们都是先用一个input选好图片,然后单独做一个提交图片的按钮,点击按钮,使用form表单提交到后台,然后通过
// 获取上传的文件 HttpPostedFileBase file = Request.Files[0];
这一行来获取上传到后台的文件,然后来验证上传的文件是不是图片,其实在前台,通过设置input属性,就可以限制我们只能选择图片文件了,当然,后台的验证也是不能少的,
// 设置accept属性,限制能选择的文件类型为图片 <input type="file" accept="image/*" id="upload" />
当我们在前台提交图片到后台,并且,在后台获取到之后,下一步,我们要做的就是上传图片了,代码如下
1 // 以‘.‘、‘..‘、‘~‘开头的路径,均为相对路径(推荐使用) 2 // 以盘符‘C:‘、‘D:‘,等开头的,均为绝对路径 3 // 上传路径,可以任意修改 4 string path = "~/upload"; 5 6 // 获取上传的文件名(包含后缀) 7 string FileName = file.FileName; 8 9 // 获取上传绝对路径,若path初始值就是绝对路径,可以忽略不写 10 path = Server.MapPath(path); 11 12 // 检测是否存在此路径,没有就创建 13 // 需引用命名空间,using System.IO; 14 if (!Directory.Exists(path)) 15 // 创建路径 16 Directory.CreateDirectory(path); 17 18 // 上传文件 19 file.SaveAs(path + FileName);
其实写到这里图片上传就已经成功了,但是,凡事都会有个但是!!
原生的input选择图片之后,只能显示一个文件名吧,如果我们想选择图片之后,立刻能够看到我们选择的图片,那么问题就来了,怎么办???
曾经做过一次这种效果,当然,灰常麻烦,早就不用了,不过大概的思路还是讲讲吧
- 给input加一个onchange事件,每次选择的文件修改之后就会触发
- 在onchange事件中添加一个方法(Uoplad),这个方法要执行的功能就是提交input所在的form表单
- 提交form表单后,在后台将提交上来的图片文件保存在指定位置(path)
- 这时候path位置肯定有那张图片,在方法Upload中,我们就可以直接取path位置拿图片,更新一下指定img的src属性就好
这样写是可以实现图片选择之后,立刻显示的效果的,操作麻烦不说,问题也有很多,如果我们一直挑选图片,那些被我们挑过但是不用的图片都会被上传,大量的垃圾数据就这样产生了,而且,反复提交form表单,对网站的负担也会比较大的,都说度娘是万能的,果不其然,找了很久之后,终于被我找到了一个非常不错的方法
前端js方法:
1 // 选择图片预览方法 2 // ImgID,显示预览图片的img标签id 3 // FileInputID,选择文件的input标签id 4 // MaxLengt,能选择的最大文件大小(单位:mb),默认2M,可以忽略不填 5 function ChangImg(ImgID, FileInputID, MaxLength = 2.0) { 6 7 // 触发Input单击事件 8 $("#" + FileInputID).click(); 9 10 // Input单击执行 11 $("#" + FileInputID).on("change", function () { 12 13 //设置上传的文件最大值(单位:M),超过此值则不上传。 14 var flength = MaxLength; 15 var size = this.files[0].size; 16 17 size = (size / 1024 / 1024).toFixed(2); 18 19 // 判断是否超过最大大小 20 if (size > MaxLength) { 21 alert("所选文件大小:" + size + " M,最大文件大小:" + MaxLength + " M"); 22 23 // 清空Fileinput的值 24 if (this.outerHTML) 25 this.outerHTML = this.outerHTML; 26 else 27 this.values = ""; 28 29 // 显示默认图片 30 $("#" + ImgID).attr("src", ‘/upload/Click.png‘); 31 return; 32 } 33 34 // 获取图片的路径,该路径不是图片在本地的路径 35 var objUrl = null; 36 37 // 为文件创建一个Url对象,可能会有一点点兼容性问题 38 objUrl = window.URL.createObjectURL(this.files[0]); 39 40 if (objUrl) 41 // 将图片路径存入src中,显示出图片 42 $("#" + ImgID).prop("src", objUrl); 43 44 }); 45 }
感谢那位不知名的大神,我在他的基础上进行了修改,添加了文件大小验证,因为默认只能上传两兆还是四兆的文件来着,不记得了,反正不大,如果你没有修改默认配置,而你选择的文件又偏偏超过了这个范围,提交form表单的时候绝对会炸的你不要不要的,,,
至于这个方法怎么用,我也大概的写了一套模板,跟着模板来肯定是没问题的
前端HTML代码:
1 <!-- 2 必须添加 enctype = "multipart/form-data" 属性,否则后台无法接收到上传的文件!! 3 我是基于MVC实现的,其他的其实也一样,略微修改就好 4 嗯,我也没有加CSS,你们随意加,, 5 --> 6 <form action="/Home/Upload" enctype = "multipart/form-data"> 7 <p> 8 <label>选择图片:</label> 9 <label> 10 <!-- 预览的图片,单击它就可以选择图片 --> 11 <img src="~/images/Click.png" id="pic" title="单击选择图片" onclick="ChangImg(‘pic‘,‘upload‘)" /> 12 <!-- 单击图片,其实触发的是它的单击事件,将其隐藏起来更美观 --> 13 <input type="file" accept="image/*" id="upload" style="display:none;" /> 14 </label> 15 </p> 16 <!-- 单击按钮,即可开始上传 --> 17 <p> <input type="submit" value="开始上传" /></p> 18 </form>
后台代码:
1 // 2 public ActionResult Upload(){ 3 // 参数看着给,所有的参数都有默认值,都可以修改成自己常用的值 4 string fileUrl = SaveFile(); 5 6 // 若要获取多文件上传的值,使用splitChar参数的值进行分割就好,默认splitChar=‘;‘,即 7 // string[] res=fileUrl.Split(‘;‘); 8 9 // 判断fileUrl是否为空,若为空,表示没有上传文件 10 if(string.IsNullOrEmpty(fileUrl)) 11 return Content("上传失败!"); 12 // 不为空时,上传成功 13 else 14 return Content("上传成功!"); 15 } 16 17 18 #region 图片上传,此方法可以通用 19 20 /// <summary> 21 /// 上传图片 22 /// </summary> 23 /// <param name="type">存储方式,默认按年份分类</param> 24 /// <param name="path">上传路径,默认值可以更改为自己常用的地址</param> 25 /// <param name="IsUrl">是否返回路径,若不返回路径,就返回文件名称</param> 26 /// <param name="format">文件名格式</param> 27 /// <param name="splitChar">多文件路径分割符</param> 28 /// <returns>默认返回图片上传的相对路径,IsUrl为false时,返回图片名称</returns> 29 public string SaveFile(SaveType type = SaveType.ForYear, string path = "~/upload/",bool IsUrl=true, string format = "yyyyMMddHHmmssffff", char splitChar = ‘;‘) { 30 // 返回所有的上传路径,以splitChar分割 31 string resUrl = ""; 32 // 图片格式数组 33 string[] imgFormat = { ".bmp", ".gif", ".png", ".jpg", ".jpeg" }; 34 35 // 循环所有的上传文件 36 for (int i = 0; i < Request.Files.Count; i++) { 37 38 // 上传图片 39 HttpPostedFileBase file = Request.Files[i]; 40 string FileName = file.FileName; // 上传的原文件名 41 42 if (FileName.Length > 0) { 43 44 // 获取文件后缀名 45 string Suffix = FileName.Substring(FileName.LastIndexOf(‘.‘)); 46 47 // 判断文件是否为图片,若不是图片,跳出,检测下一个文件 48 if (Array.IndexOf(imgFormat, Suffix) == -1) 49 continue; 50 51 // 拼接文件名称 52 DateTime dateNow = DateTime.Now; 53 FileName = dateNow.ToString(format) + Suffix; 54 55 // 根据存储方式,修改路径 56 // 增加年份文件夹 57 if (Convert.ToInt32(type) >= 1) 58 path += dateNow.Year + "/"; 59 // 增加月份文件夹 60 if (Convert.ToInt32(type) >= 2) 61 path += dateNow.Month + "/"; 62 // 增加年份文件夹 63 if (Convert.ToInt32(type) >= 3) 64 path += dateNow.Day + "/"; 65 66 // 若有多个文件要上传,将它们一一进行拼接 67 if (!string.IsNullOrEmpty(resUrl)) 68 resUrl += splitChar; 69 70 // 若返回相对路径(默认) 71 if(IsUrl) 72 // .Substring(1),用于去掉第一个字符‘~‘,可视情况修改或去掉 73 resUrl += (path + FileName).Substring(1); 74 // 若返回文件名称 75 else 76 resUrl += FileName; 77 78 // 获取上传绝对路径 79 path = Server.MapPath(path); 80 81 // 检测是否存在此路径,没有就创建 82 if (!Directory.Exists(path)) 83 // 创建路径 84 Directory.CreateDirectory(path); 85 86 // 上传图片 87 file.SaveAs(path + FileName); 88 } 89 } 90 return resUrl; 91 } 92 93 /// <summary> 94 /// 文件存储方式,枚举 95 /// </summary> 96 public enum SaveType { 97 /// <summary> 98 /// 直接上传至指定目录 99 /// </summary> 100 ForNone = 0, 101 /// <summary> 102 /// 按年份区分上传,每一年的图片在同一个文件夹 103 /// </summary> 104 ForYear = 1, 105 /// <summary> 106 /// 按月份区分上传,每个月的图片在同一个文件夹 107 /// </summary> 108 ForMonth = 2, 109 /// <summary> 110 /// 按天份区分上传,每一天的图片在同一个文件夹 111 /// </summary> 112 ForDay = 3 113 } 114 #endregion
嗯,到这就差不多,能耐心读到这里的都是一个好读者啊,嘿嘿,谢啦,希望能对你们有所帮助,,,
时间: 2024-10-26 08:02:39