Preface:
The talk is to use .Net HttpClient stitching multipark / form-data form post upload files and related parameters, and return received over after a successful file upload results (picture address, and if successful). There may be a lot of people would say not with ajax can easily achieve it? Indeed using ajax upload files without the presence of cross-domain issues, receives the result is the best option. Frustratingly, there is our butt is a third-party interface to upload pictures, and the other party does not allow cross-domain settings on our domain, in order to solve this problem we can only avoid cross-domain request by the back-end problem.
What is a multipart / form-data request:
About multipart / form-data details View: https://www.cnblogs.com/tylerdonet/p/5722858.html
Html Upload Picture button:
<div class="cover-hd"> <a href="javascript:;" class="a-uploadCustom"> <input type="file" id="Logoimg" onchange="OnchangeImage(this)" /></a> </div>
Use ajax to transfer image files to the back-end flow and associated parameters for splicing:
Note: Because I am here to call third-party interfaces need to pass (appid application to uniquely identify, random random number, and sign the signature)
<Script type = " text / JavaScript " > // rear image upload function OnchangeImage (obj) { var formData = new new the FormData (); var Files = $ (obj) .prop ( ' Files ' ); // acquired file listing the console.log (Files [ 0 ]); formData.append ( " imgType " , . 1 ); formData.append ( " for appId " , " parameters you need to pass a " ); formData.append ( "Random " , " parameter you need to pass " ); formData.append ( " File " , Files [ 0 ]); // Image file stream formData.append ( " Sign " , " parameter you need to pass " ); Console. log (formData); jQuery.support.cors = to true ; $ .ajax ({ the async : to true , contentType: to false , // header request content format dataType: ' JSON ', Of the type: ' POST ' , the Data: formData, // tell jQuery not to handle data sent processData: false , url: " @ Url.Action ( " ImageUpload " , " MtVirtualStore " ) " , // backend interface to receive pictures success: function (Data) { // rear end Httpclient successful request results returned over the console.log (Data); } }); } </ Script>
Receive pictures and back-end parameters, and image files byte stream into the picture type data:
//接收前端图片文件信息 [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= Path.GetFileName fileName (fileData.FileName); // original file name byte [] = byteFileData ReadFileBytes (fileData); // file stream into a stream of bytes var The ResultContext = HttpClientPostUpload (byteFileData, for appId, Random, Sign, imgType, fileName ); return Json ( new new {code = . 1 , List The ResultContext =, = MSG " uploaded successfully ~ " }); } the catch (Exception EX) { return Json ( new new {code = 0 , MSG = ex.Message}); } } the else { return Json ( new newCode = { 0 , MSG = " images failed to upload, please try again later ~ " }); } } // File stream into byte /// <Summary> /// file type into the stream type byte // / </ Summary> /// <param name = "fileData"> file streaming data </ param> /// <Returns> </ Returns> Private byte [] ReadFileBytes (HttpPostedFileBase fileData) { byte [] data; the using ( = inputStream Stream fileData.InputStream) { the MemoryStream MemoryStream = inputStream AS the MemoryStream; IF (memoryStream == null) { memoryStream = new MemoryStream(); inputStream.CopyTo(memoryStream); } data = memoryStream.ToArray(); } return data; }
Key, HttpClient stitching multipart / form-data form to submit data parameters post:
/// <Summary> /// submitted document image data to the target address parameter /// </ Summary> /// <param name = "bmpBytes"> Image byte stream </ param> /// <param name = "for appId"> AppID </ param> /// <param name = "random"> random </ param> /// <param name = "Sign"> signature </ param> /// <param name = " imgType "> upload pictures type </ param> /// <param name =" fileName "> Image name </ param> /// <returns A> </ returns A> 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);//Image padding bytes fileContent.Headers.ContentDisposition = new new ContentDispositionHeaderValue ( " form-Data " ) { the Name = " File " , FileName = fileName }; list.add (fileContent); the using ( var Content = new new MultipartFormDataContent ()) { the Action <List <byteArrayContent ACT >> = (dataContents) => { // declare a delegate that role is added to the set byteArrayContent MultipartFormDataContent in the 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; } } } }
Use Fiddler 4 Ethereal see the requested parameters:
Because we can not see multipark / form-data form after we successfully spliced data, we want to see the corresponding request parameter stitching can use Fiddler 4 packet capture tool to view:
About Fiddler 4 using the packet capture tool can read this blog post: https://www.jianshu.com/p/55f7be58a7e4
Capture acquired multipark / form-data request in the form of parameters as shown below:
to sum up:
Wrote finally find that only need a simple request to cross-domain problem can be solved because this issue has become so complicated, and made really makes egg pain. Here I tried stitching multipark / form-data in the form of a variety of ways request parameters, and finally in the persistent attempts finally succeeded.