• 本地服务的文件上传与远程服务的文件上传(图片上传)


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

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

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

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

     1 <style>
     2         .uploader {
     3             border: 1px dashed #d9d9d9;
     4             border-radius: 6px;
     5             cursor: pointer;
     6             position: relative;
     7             overflow: hidden;
     8         }
     9 
    10             .uploader:hover {
    11                 border-color: #409EFF;
    12             }
    13 
    14         .avatar-uploader-icon {
    15             font-size: 28px;
    16             color: #8c939d;
    17             text-align: center;
    18         }
    19 
    20         .banners-size {
    21             width: 280px;
    22             height: 120px;
    23             line-height: 120px;
    24         }
    25 
    26         .avatar-banners {
    27             width: 280px;
    28             height: 120px;
    29             background-size: cover;
    30         }
    31 
    32         .el-upload__tip {
    33             color: red;
    34         }
    35     </style>
    View Code
     1 <el-upload class="upload-demo"
     2            ref="banners"
     3            :limit="1"
     4            action="https://jsonplaceholder.typicode.com/posts/"
     5            accept="image/jpeg,image/png"
     6            name="bannersImg"
     7            :http-request="uploadFile"
     8            :auto-upload="false">
     9     <el-button slot="trigger" size="small" type="primary" v-on:click="selectUpload('bannersImg')">选取文件</el-button>
    10     <el-button style="margin-left: 10px;" size="small" type="success" v-on:click="submitUpload('bannersImg')">确定上传</el-button>
    11     <div slot="tip" class="el-upload__tip">只能上传jpg文件,且不超过200kb,尺寸:440x240</div>
    12 </el-upload>
    13 <div class="uploader banners-size">
    14     <img v-if="banners_imageUrl" :src="banners_imageUrl" class="avatar-banners">
    15 </div>

    前端核心代码:

     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 kb
    31                     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, URLSearchParams
    68                         headers: { "Content-Type": "multipart/form-data;charset=UTF-8" },
    69                     });
    70                 }
    View Code

    本地服务器上传接口:

     1         /// <summary>
     2         /// 本地上传图片
     3         /// </summary>
     4         /// <returns></returns>
     5         [HttpPost]
     6         public JsonResult UploadImg(string filename)
     7         {
     8             var result = new Common.CommonResult(1, "网络请求错误");
     9             try
    10             {
    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         /// <summary>
     2         /// 上传文件到本地
     3         /// </summary>
     4         /// <param name="filename"></param>
     5         /// <param name="basePath"></param>
     6         /// <param name="bytes"></param>
     7         /// <returns></returns>
     8         public static string UploadFile(byte[] bytes,string basePath, string filename)
     9         {
    10             string result = "";
    11             try
    12             {
    13                 if (bytes != null)
    14                 {
    15                     //保存文件路径,比如:\Images\2020-01-01\,这里的basePath相当于\Images
    16                     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.jpg
    24                     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.jpg
    34                     result = (upfilePath + filename).Replace("\", "/");
    35                 }
    36                 else
    37                 {
    38                     result = "上传的文件信息不存在!";
    39                 }
    40             }
    41             catch (Exception ex)
    42             {
    43                 return "";
    44             }
    45             return result;
    46         }

    一般向本地服务器上传的同时,还要向cdn服务器上传一份,请求cdn服务器接口代码如下:

     1         /// <summary>
     2         /// 上传文件到远程服务器
     3         /// </summary>
     4         /// <param name="bytes"></param>
     5         /// <param name="basepath"></param>
     6         /// <param name="filename"></param>
     7         /// <returns></returns>
     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             try
    13             {
    14                 var apiurl = hosturl + "api/UpLoad/ReceiveFile";  //远程请求接口 相当于:https://cache.xxxxxx.com:8080/api/UpLoad/ReceiveFile
    15                 HttpClient httpClient = HttpClientFactory.GetHttpClient();
    16                 string upfilePath = basepath + "\" + DateTime.Now.ToString("yyyy-MM-dd") + "\";  //保存路径,比如:\Images\2020-01-01\,basepath相当于\Images
    17                 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     /// <summary>
     2     /// 文件上传服务
     3     /// </summary>
     4     public class UpLoadController : ApiController
     5     {
     6         /// <summary>
     7         /// 文件接收接口
     8         /// </summary>
     9         /// <returns></returns>
    10         [HttpPost]
    11         public HttpResponseMessage ReceiveFile()
    12         {
    13             HttpResponseMessage response = null;
    14             try
    15             {
    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);  //成功返回200
    44             }
    45             catch (Exception)
    46             {
    47                 response = Request.CreateResponse(HttpStatusCode.BadRequest); //返回400
    48             }
    49             return response;
    50         }
    51 
    52     }
  • 相关阅读:
    网络IO之阻塞、非阻塞、同步、异步总结
    C语言栈与调用惯例
    多个文件目录下Makefile的写法
    利用 mount 指令解决 Read-only file system的问题
    error while loading shared libraries: xxx.so.x" 错误的原因和解决办法
    Centos6.4下安装protobuf及简单使用
    Centos下修改启动项和网络配置
    Centos下配置单元测试工具gtest
    Centos配置为驱动程序开发环境
    Centos安装gcc及g++
  • 原文地址:https://www.cnblogs.com/peterzhang123/p/13524025.html
Copyright © 2020-2023  润新知