本次要讲的是使用.Net HttpClient拼接multipark/form-data形式post上传文件和相关参数,并接收到上传文件成功后返回过来的结果(图片地址,和是否成功)。可能有不少人会说用ajax不是就能够轻松的实现吗?的确是在不存在跨域问题的前提下使用ajax上传文件,接收返回结果是最佳的选择。无奈的是咱们对接的是第三方的一个上传图片的接口,并且对方并无对咱们的域名设置容许跨域,为了可以解决这一问题咱们只可以经过后端请求避免跨域问题。javascript
关于multipart/form-data详情查看: http://www.javashuo.com/article/p-fiiqzgkp-cu.htmlhtml
<div class="cover-hd"> <a href="javascript:;" class="a-uploadCustom"> <input type="file" id="Logoimg" onchange="OnchangeImage(this)" /></a> </div>
注意:由于我这里调用第三方接口须要传递(appid应用程序惟一标识,random随机数,和sign签名)前端
<script type="text/javascript"> //后端图片上传 function OnchangeImage(obj) { var formData = new FormData(); var files = $(obj).prop('files'); //获取到文件列表 console.log(files[0]); formData.append("imgType", 1); formData.append("appId","你须要传递的参数"); formData.append("random", "你须要传递的参数"); formData.append("file", files[0]);//图片文件流 formData.append("sign", "你须要传递的参数"); console.log(formData); jQuery.support.cors = true; $.ajax({ async: true, contentType: false, //头部请求内容格式 dataType: 'json', type: 'post', data:formData, // 告诉jQuery不要去处理发送的数据 processData: false, url: "@Url.Action("ImageUpload", "MtVirtualStore")",//后端接收图片接口 success: function(data) { //后端Httpclient请求成功后返回过来的结果 console.log(data); } }); } </script>
//接收前端图片文件信息 [HttpPost] public JsonResult ImageUpload(FormContext context) { HttpPostedFileBase fileData = Request.Files[0]; string appId=Request["appId"]; string random=Request["random"]; string sign=Request["sign"]; string imgType=Request["imgType"]; if (fileData != null) { try{ string fileName = Path.GetFileName(fileData.FileName);//原始文件名称 byte[] byteFileData = ReadFileBytes(fileData);//文件流转为字节流 var resultContext =HttpClientPostUpload(byteFileData,appId,random,sign,imgType, fileName); return Json(new { code = 1, list = resultContext,msg="上传成功~"}); } catch (Exception ex) { return Json(new { code = 0, msg = ex.Message }); } } else { return Json(new { code = 0, msg = "图片上传失败,请稍后再试~" }); } } //文件流转化为字节 /// <summary> /// 文件流类型转化字节类型 /// </summary> /// <param name="fileData">文件流数据</param> /// <returns></returns> private byte[] ReadFileBytes(HttpPostedFileBase fileData) { byte[] data; using (Stream inputStream = fileData.InputStream) { MemoryStream memoryStream = inputStream as MemoryStream; if (memoryStream == null) { memoryStream = new MemoryStream(); inputStream.CopyTo(memoryStream); } data = memoryStream.ToArray(); } return data; }
/// <summary> /// 向目标地址提交图片文件参数数据 /// </summary> /// <param name="bmpBytes">图片字节流</param> /// <param name="appId">appid</param> /// <param name="random">随机数</param> /// <param name="sign">签名</param> /// <param name="imgType">上传图片类型</param> /// <param name="fileName">图片名称</param> /// <returns></returns> public string HttpClientPostUpload(byte [] bmpBytes, string appId, string random,,string sign,string imgType,string fileName) { using (var client = new HttpClient()) { List<ByteArrayContent> list = new List<ByteArrayContent>(); var dataContent = new ByteArrayContent(Encoding.UTF8.GetBytes(appId)); dataContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")//内容处置标头 { Name = "appId" }; list.Add(dataContent); var dataContent2 = new ByteArrayContent(Encoding.UTF8.GetBytes(imgType)); dataContent2.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = "imgType" }; list.Add(dataContent2); var dataContent3 = new ByteArrayContent(Encoding.UTF8.GetBytes(random)); dataContent3.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = "random" }; list.Add(dataContent3); var dataContent4 = new ByteArrayContent(Encoding.UTF8.GetBytes(sign)); dataContent4.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = "sign" }; list.Add(dataContent4); List<ByteArrayContent> list2 = new List<ByteArrayContent>(); var fileContent = new ByteArrayContent(bmpBytes);//填充图片字节 fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name="file", FileName=fileName }; list.Add(fileContent); using (var content =new MultipartFormDataContent()) { Action<List<ByteArrayContent>> act = (dataContents) => {//声明一个委托,该委托的做用就是将ByteArrayContent集合加入到MultipartFormDataContent中 foreach (var byteArrayContent in dataContents) { content.Add(byteArrayContent); } }; act(list);//执行act try { var result = client.PostAsync("https://xxxxxx.com/imageUpload/", content).Result;//post请求 return result.Content.ReadAsStringAsync().Result; } catch (Exception ex) { return ex.Message; } } } }
由于咱们没有办法看到咱们所拼接成功后的multipark/form-data形式的数据,想要看到对应拼接的请求参数能够使用 Fiddler 4 抓包工具查看:java
关于Fiddler 4抓包工具的使用能够阅读该篇博客:https://www.jianshu.com/p/55f7be58a7e4ajax
抓包获取到的multipark/form-data形式的请求参数以下图:json
写到最后才发现,本来只须要一个简单的请求就能够解决的问题由于跨域把这个问题变得如此繁琐,搞得真叫人蛋痛。这里我试过了不少种方式拼接multipark/form-data形式的请求参数,最后在坚持不懈的尝试下终于成功了。后端