文件上传属于常见业务,很多地方都用的到(比如图片上传);

确切的说,这里的“本地”是指的项目所在的服务端,只是在项目服务端再次请求另外一个服务端进行文件二次上传。

比如:我们上传图片的时候,请求项目的服务器需要上传一份,同时还要上传一份到cdn服务器。

示例使用控件: el-upload 作为演示

本地服务的文件上传与远程服务的文件上传(图片上传)_第1张图片

ContractedBlock.gif ExpandedBlockStart.gif
 1 
View Code
 1  9  选取文件10  确定上传11  
只能上传jpg文件,且不超过200kb,尺寸:440x240
12
13
14 15

前端核心代码:

ContractedBlock.gif ExpandedBlockStart.gif
 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

本地服务器上传接口:

ContractedBlock.gif ExpandedBlockStart.gif
 1   ///  2   /// 本地上传图片 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   }
View Code

上传本地文件处理方法: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上即可

本地服务的文件上传与远程服务的文件上传(图片上传)_第2张图片

然后客户端请求路径: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