文件上传属于常见业务,很多地方都用的到(比如图片上传);
确切的说,这里的“本地”是指的项目所在的服务端,只是在项目服务端再次请求另外一个服务端进行文件二次上传。
比如:我们上传图片的时候,请求项目的服务器需要上传一份,同时还要上传一份到cdn服务器。
示例使用控件: el-upload 作为演示
1View Code
19 13选取文件 10确定上传 11只能上传jpg文件,且不超过200kb,尺寸:440x24012
前端核心代码:
1 //选取文件 2 selectUpload: function (obj) { 3 this.clearFiles(obj); 4 }, 5 //确定上传 6 submitUpload: function (obj) { 7 this.$refs.banners.submit(); 8 }, 9 //清除文件状态10 clearFiles: function (filename) {11 this.$refs.banners.clearFiles();12 },13 14 //文件上传15 uploadFile: function (params) {16 //console.log(params);17 var _filename = params.filename;18 19 //判断图片格式20 const isJPG = params.file.type === 'image/jpeg';21 if (!isJPG) {22 this.$message.error('上传图片只能是 JPG 格式!');23 this.clearFiles(_filename);24 return isJPG;25 }26 this.BannersUpload(params.file);27 },28 //图片上传29 BannersUpload: function (file) {30 const isLtSize = file.size / 1024 / 1024 / 1024 < 20; //不能超过xx kb31 if (!isLtSize) {32 this.$message.error('上传图片大小不能超过 20kb!');33 this.clearFiles(file.filename);34 return isLtSize;35 }36 37 //执行上传操作38 this.FileUpload(file)39 .then(res => { //返回结果40 var getResult = JSON.parse(res.data);41 //成功42 if (getResult.Code == 0) {43 this.$message.success('上传成功');44 this.banners_imageUrl = getResult.Data;45 this.addForm.BannersImg = getResult.Data;46 }47 //错误48 if (getResult.Code == 1) {49 if (getResult.Message) {50 this.$message.error(getResult.Message);51 }52 }53 }).catch(function (res) {54 this.$message.success('请求异常');55 });56 },57 //文件上传58 FileUpload: function (file) {59 var fd = new FormData();60 fd.append("filedata", file);61 //异步获取62 return axios.request({63 method: 'post',64 baseURL: this.apiUrl,65 url: '/WxLive/UploadImg',66 params: { "filename": "filedata" }, //是即将与请求一起发送的 URL 参数67 data: fd, //浏览器专属:FormData, File, Blob 必须是以下类型之一:string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams68 headers: { "Content-Type": "multipart/form-data;charset=UTF-8" },69 });70 }View Code
本地服务器上传接口:
1 ///View Code2 /// 本地上传图片 3 /// 4 ///5 [HttpPost] 6 public JsonResult UploadImg(string filename) 7 { 8 var result = new Common.CommonResult(1, "网络请求错误"); 9 try10 {11 string basePath = ConfigurationManager.AppSettings["basePath"] ?? "\\Images"; //服务器上传文件夹12 string imgpath = string.Empty;13 14 HttpPostedFileBase file = Request.Files.Get(filename); //从browser传过来的的文件15 //HttpPostedFile file = System.Web.HttpContext.Current.Request.Files.Get(filename); //从browser传过来的的文件16 17 if (file != null && file.ContentLength > 0)18 {19 //文件后缀名20 string fileExtension = Path.GetExtension(file.FileName).ToLower();21 22 //获取文件名23 string fileName = DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss_ffff");24 fileName += fileExtension;25 26 Stream postStream = file.InputStream;27 byte[] bytes = new byte[postStream.Length];28 postStream.Read(bytes, 0, file.ContentLength);29 postStream.Seek(0, SeekOrigin.Begin); //设置当前流的位置为流的开始 30 postStream.Close();31 32 //写入本地33 var repath = UploadHelper.UploadFile(bytes, basePath, fileName);34 35 result.Code = 0;36 result.Message = "OK";37 result.Data = repath;38 }39 return Json(JsonConvert.SerializeObject(result));40 }41 catch (Exception)42 {43 return Json(JsonConvert.SerializeObject(result));44 }45 }
上传本地文件处理方法:UploadHelper.UploadFile()
1 ///2 /// 上传文件到本地 3 /// 4 /// 5 /// 6 /// 7 ///8 public static string UploadFile(byte[] bytes,string basePath, string filename) 9 {10 string result = "";11 try12 {13 if (bytes != null)14 {15 //保存文件路径,比如:\\Images\\2020-01-01\\,这里的basePath相当于\\Images16 string upfilePath = basePath + "\\" + DateTime.Now.ToString("yyyy-MM-dd") + "\\"; //根路径17 //上传到本地 ~/表示上级目录,如果不加则表示同级目录18 string filePath = System.Web.HttpContext.Current.Server.MapPath("~/" + upfilePath);19 if (!Directory.Exists(filePath))20 {21 Directory.CreateDirectory(filePath);22 }23 //完整路径:项目目录\\Images\\2020-01-01\\abc.jpg24 string fileSavePath = Path.Combine(filePath, filename); //合并成完整的文件路径25 26 //写入本地27 using (FileStream fs = new FileStream(fileSavePath, FileMode.Create))28 {29 fs.Write(bytes, 0, bytes.Length);30 fs.Close();31 fs.Dispose();32 }33 //返回路径:/Images/2020-01-01/abc.jpg34 result = (upfilePath + filename).Replace("\\", "/");35 }36 else37 {38 result = "上传的文件信息不存在!";39 }40 }41 catch (Exception ex)42 {43 return "";44 }45 return result;46 }
一般向本地服务器上传的同时,还要向cdn服务器上传一份,请求cdn服务器接口代码如下:
1 ///2 /// 上传文件到远程服务器 3 /// 4 /// 5 /// 6 /// 7 ///8 public static string PostUploadFile(byte[] bytes, string basepath, string filename) 9 {10 string repath = "";11 string hosturl = ConfigurationManager.AppSettings["apihost"] ?? "https://cache.xxxxxx.com:8080/"; //远程服务器路径12 try13 {14 var apiurl = hosturl + "api/UpLoad/ReceiveFile"; //远程请求接口 相当于:https://cache.xxxxxx.com:8080/api/UpLoad/ReceiveFile15 HttpClient httpClient = HttpClientFactory.GetHttpClient();16 string upfilePath = basepath + "\\" + DateTime.Now.ToString("yyyy-MM-dd") + "\\"; //保存路径,比如:\\Images\\2020-01-01\\,basepath相当于\\Images17 using (var multipartFormDataContent = new MultipartFormDataContent()) //MultipartFormDataContent相当于 "Content-Type": "multipart/form-data"18 {19 //二进制流传输,远程服务器可以使用: Request.Files.Get("filedata")接收20 multipartFormDataContent.Add(new ByteArrayContent(bytes, 0, bytes.Length), "filedata", filename);21 //远程服务器可以使用: Request["filePath"]接收22 multipartFormDataContent.Add(new StringContent(upfilePath, Encoding.UTF8, "application/x-www-form-urlencoded"), "filePath");23 24 //post请求25 var response = httpClient.PostAsync(apiurl, multipartFormDataContent).Result;26 if (response.StatusCode == System.Net.HttpStatusCode.OK)27 {28 var result = response.Content.ReadAsStringAsync().Result;29 if ((int)response.StatusCode == 200)30 {31 repath = (upfilePath + filename).Replace("\\", "/");32 }33 }34 }35 return repath;36 }37 catch (Exception ex)38 {39 return repath;40 }41 }
接下来看看在远程cdn服务器上如何接收本地服务器上传过来的文件,实际上跟本地服务上传没多大区别。
创建一个文件上传服务,比如创建一个WebApI服务,创建一个文件上传接口:/api/UpLoad/ReceiveFile,然后将该服务发布到IIS上即可
然后客户端请求路径:https://cache.xxxxxx.com:8080/api/UpLoad/ReceiveFile
1 ///2 /// 文件上传服务 3 /// 4 public class UpLoadController : ApiController 5 { 6 ///7 /// 文件接收接口 8 /// 9 ///10 [HttpPost]11 public HttpResponseMessage ReceiveFile()12 {13 HttpResponseMessage response = null;14 try15 {16 HttpPostedFile file = HttpContext.Current.Request.Files.Get("filedata"); //获取文件流17 string getfilepath = HttpContext.Current.Request["filePath"] ?? "\\Images\\"; //获取保存路径(不包含文件名),默认:\\Images\\18 var filename = file.FileName; //获取文件名19 20 //保存到本地的路径,~/表示指向上级根目录21 string savePath = HttpContext.Current.Server.MapPath("~/" + getfilepath);22 23 //创建文件夹24 if (!Directory.Exists(savePath))25 {26 Directory.CreateDirectory(savePath);27 }28 29 //保存文件到指定路径下30 string saveFilePath = Path.Combine(savePath, filename);31 Stream postStream = file.InputStream;32 using (FileStream fs = new FileStream(saveFilePath, FileMode.Create))33 {34 byte[] new_b = new byte[postStream.Length];35 while (postStream.Read(new_b, 0, new_b.Length) != 0)36 {37 fs.Write(new_b, 0, new_b.Length);38 }39 postStream.Close();40 fs.Close();41 fs.Dispose();42 }43 response = Request.CreateResponse(HttpStatusCode.OK); //成功返回20044 }45 catch (Exception)46 {47 response = Request.CreateResponse(HttpStatusCode.BadRequest); //返回40048 }49 return response;50 }51 52 }
本地服务的文件上传与远程服务的文件上传(图片上传)
文章转载:http://www.shaoqun.com/a/464525.html