本地服務的文件上傳與遠程服務的文件上傳(圖片上傳)

文件上傳屬於常見業務,不少地方都用的到(好比圖片上傳);前端

確切的說,這裏的「本地」是指的項目所在的服務端,只是在項目服務端再次請求另一個服務端進行文件二次上傳。ios

好比:咱們上傳圖片的時候,請求項目的服務器須要上傳一份,同時還要上傳一份到cdn服務器。json

示例使用控件: el-upload 做爲演示axios

 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>

前端核心代碼:api

 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服務器上如何接收本地服務器上傳過來的文件,實際上跟本地服務上傳沒多大區別。app

建立一個文件上傳服務,好比建立一個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     }
相關文章
相關標籤/搜索