本以為解決跨域上傳後沒有問題了,不成想被測試找出一個問題,那就是在手機上拍照上傳後圖片會旋轉。很頭痛,不過沒有辦法,問題還是需要解決的。在查閱了一系列資料後我找到了相應的解決方案,利用exif.js獲取圖片旋轉的方向,然後再轉過來圖片,之後再上傳。這個方案需要修改前面的腳本,同樣的,由於要傳base ...
本以為解決跨域上傳後沒有問題了,不成想被測試找出一個問題,那就是在手機上拍照上傳後圖片會旋轉。很頭痛,不過沒有辦法,問題還是需要解決的。在查閱了一系列資料後我找到了相應的解決方案,利用exif.js獲取圖片旋轉的方向,然後再轉過來圖片,之後再上傳。這個方案需要修改前面的腳本,同樣的,由於要傳base64字元串,後臺也要做出相應的修改。下麵是我修改後的相應代碼:
1 (function () { 2 var imgOperate = { 3 operateUrl: "更改圖片在資料庫中的狀態地址", 4 uploadUrl: "代理圖片上傳地址", 5 DelPicId: '', 6 ddWidth: 0, 7 dlWidth:0, 8 successCount:0, 9 onload: function () { 10 this.initImage(); 11 }, 12 initImage: function () { 13 var et = $('#entrust dd').length; 14 this.ddWidth = $('#entrust dd').width() + 17; 15 this.dlWidth = parseInt(et * this.ddWidth + 160); 16 $('#entrust').css("width", this.dlWidth); 17 this.BindEvent(); 18 }, 19 BindEvent: function () { 20 var _this = this; 21 $("#pic0").on("change", function () { 22 23 _this.uploadFiles(this); 24 25 }); 26 27 }, 28 InserImage:function(urls,dd) 29 { 30 $.post(this.operateUrl, { houseid: houseid, operateType: 1, picStr: urls }, function (data) { 31 data = eval("(" + data + ")"); 32 if (data && data.picIds) 33 { 34 dd.getElementsByTagName("img")[0].setAttribute("housepicid", data.picIds); 35 } 36 }); 37 }, 38 uploadFiles: function (where) { 39 if (!houseid) { 40 this.ShowMsg("請回到第一步完善相應的信息"); 41 return; 42 } 43 var imgLength = $("#entrust dd").length - 1; 44 45 if (imgLength >= 50) 46 { 47 this.ShowMsg("你的圖片超過了50張,不能再上傳"); 48 return; 49 } 50 if (imgLength + where.files.length > 50) 51 { 52 this.ShowMsg("你選擇的圖片超過了50張,無法上傳,請重新選擇"); 53 return; 54 } 55 56 57 var _this = this; 58 var radtime = new Date(); 59 var sid = radtime.getTime(); 60 this.successCount=0; 61 for (var i = 0; i < where.files.length; i++) { 62 var formData = new FormData(); 63 var file = where.files[i]; 64 var orientation = 1; 65 66 if (file.name.indexOf("jpg") > -1) { 67 EXIF.getData(file, function () { 68 EXIF.getAllTags(this); 69 orientation = EXIF.getTag(this, 'Orientation'); 70 if (orientation) { 71 var reader = new FileReader(); 72 reader.onload = function (e) { 73 _this.getImgData(e, this.result, orientation, function (data) { 74 75 var base64String = data; 76 formData.append("icoimage", base64String); 77 _this.UploadImg(where, formData, sid, i); 78 }); 79 } 80 reader.readAsDataURL(file); 81 } else { 82 formData.append("icoimage", file); 83 _this.UploadImg(where, formData, sid, i); 84 } 85 }); 86 } else { 87 formData.append("icoimage", file); 88 _this.UploadImg(where, formData, sid, i); 89 } 90 91 92 93 } 94 95 }, 96 UploadImg: function (where, formData, sid, i) { 97 var _this = this; 98 $.ajax({ 99 url: this.uploadUrl + '?channel=頻道&sid=' + sid, 100 type: 'POST', 101 cache: false, 102 data: formData, 103 processData: false, 104 contentType: false 105 }).success(function (res) { 106 var imgsrc = res; 107 if (imgsrc == "-1" || imgsrc == "302" || imgsrc == -1 || imgsrc == 302) { 108 _this.ShowMsg("上傳失敗,照片超過10M"); 109 } else if (imgsrc.indexOf("http") != -1) { 110 var dd = document.createElement("dd"); 111 if ($("#entrust dd").length == 1) { 112 dd.innerHTML = "<div class=\"cver\">封面圖</div><a class=\"close\"></a><img src=\"" + imgsrc + "\" housepicid=\"\">"; 113 } else { 114 dd.innerHTML = "<a class=\"close\"></a><img src=\"" + imgsrc + "\" housepicid=\"\">"; 115 } 116 document.getElementById("entrust").appendChild(dd); 117 _this.dlWidth += _this.ddWidth + 17; 118 $('#entrust').css("width", _this.dlWidth); 119 _this.InserImage(imgsrc, dd); 120 this.successCount++; 121 _this.ShowMsg("正在上傳第" + i + "張圖片"); 122 } 123 if (i == where.files.length) { 124 if (this.successCount > 0) { 125 _this.ShowMsg("成功上傳" + successCount + ",可繼續上傳新照片"); 126 } 127 } 128 129 }) 130 }, 131 ShowMsg: function (text, mymethod) { 132 var radtime = new Date(); 133 var sid = radtime.getTime(); 134 var msg_div = "<div class='zuopenbox' id='div_msg" + sid + "'><div class='opencon_01'><div class='openList'><h3 class='f15' style='margin-bottom: 0; color: #FFFFFF'>" + text + "</h3></div></div></div>"; 135 136 $(msg_div).appendTo("body"); 137 var _this = this; 138 setTimeout(function () { 139 var d = 0.5; 140 var m = document.getElementById("div_msg"+sid); 141 m.style.webkitTransition = '-webkit-transform ' + d + 's ease-in, opacity ' + d + 's ease-in'; 142 m.style.opacity = '0'; 143 setTimeout(_this.RemoveNode(m), 500); 144 }, 500); 145 }, 146 RemoveNode: function (m) { 147 m.parentNode.removeChild(m); 148 }, 149 // @param {string} img 圖片的base64 150 // @param {int} dir exif獲取的方向信息 151 // @param {function} next 回調方法,返回校正方向後的base64 152 getImgData: function (e,img, dir, next) { 153 var _this = this; 154 var image = new Image(); 155 image.src = e.target.result; 156 image.onload=function(){ 157 var degree=0,drawWidth,drawHeight,width,height; 158 drawWidth=this.naturalWidth; 159 drawHeight=this.naturalHeight; 160 //以下改變一下圖片大小 161 var maxSide = Math.max(drawWidth, drawHeight); 162 if (maxSide > 1024) { 163 var minSide = Math.min(drawWidth, drawHeight); 164 minSide = minSide / maxSide * 1024; 165 maxSide = 1024; 166 if (drawWidth > drawHeight) { 167 drawWidth = maxSide; 168 drawHeight = minSide; 169 } else { 170 drawWidth = minSide; 171 drawHeight = maxSide; 172 } 173 } 174 var canvas=document.createElement('canvas'); 175 canvas.width=width=drawWidth; 176 canvas.height=height=drawHeight; 177 var context = canvas.getContext('2d'); 178 //判斷圖片方向,重置canvas大小,確定旋轉角度,iphone預設的是home鍵在右方的橫屏拍攝方式 179 switch(dir){ 180 case 2: 181 context.translate(width, 0); 182 context.scale(-1, 1); 183 break; 184 case 3: 185 context.translate(width, height); 186 context.rotate(Math.PI); 187 break; 188 case 4: 189 context.translate(0, height); 190 context.scale(1, -1); 191 break; 192 case 5: 193 context.rotate(0.5 * Math.PI); 194 context.scale(1, -1); 195 break; 196 case 6: 197 context.rotate(0.5 * Math.PI); 198 context.translate(0, -height); 199 break; 200 case 7: 201 context.rotate(0.5 * Math.PI); 202 context.translate(width, -height); 203 context.scale(-1, 1); 204 break; 205 case 8: 206 context.rotate(-0.5 * Math.PI); 207 context.translate(-width, 0); 208 break; 209 210 } 211 212 context.drawImage(this,0,0,drawWidth,drawHeight); 213 //返回校正圖片 214 next(canvas.toDataURL("image/jpeg",.8)); 215 } 216 image.src=img; 217 } 218 219 } 220 221 imgOperate.onload(); 222 window.imgOperate = imgOperate; 223 224 })(); 225前端腳本
1 public override void ProcessRequest(HttpContext context) 2 { 3 //獲取目標站點地址 4 String target = "圖片伺服器地址"; 5 string sid = context.Request["sid"]; 6 target = string.Format("{0}?city=&channel=頻道&sid={1}&backurl=",target,sid); 7 string imgText = string.Empty; 8 if (context.Request.Files.Count == 0 && string.IsNullOrEmpty(imgText=context.Request["icoimage"])) 9 { 10 Response.Write("0"); 11 Response.End(); 12 } 13 14 Stream stream = new MemoryStream(); 15 string fileName = string.Empty; 16 byte[] bArr = null; 17 if (context.Request.Files.Count > 0) 18 { 19 var file = context.Request.Files[0]; 20 fileName = file.FileName; 21 stream = file.InputStream; 22 bArr = new byte[stream.Length]; 23 stream.Read(bArr, 0, bArr.Length); 24 stream.Close(); 25 } 26 else { 27 imgText = HttpUtility.UrlDecode(imgText); 28 imgText = Regex.Match(imgText, "(?<=,).*").Value; 29 imgText= imgText.Trim().Replace("%", "").Replace(",", "").Replace(" ", "+"); 30 if (imgText.Length % 4 > 0) 31 { 32 imgText = imgText.PadRight(imgText.Length + 4 - imgText.Length % 4, '='); 33 } 34 bArr=Convert.FromBase64String(imgText); 35 36 fileName = "base64.png"; 37 38 } 39 HttpWebRequest request = WebRequest.Create(target) as HttpWebRequest; 40 CookieContainer cookieContainer = new CookieContainer(); 41 request.CookieContainer = cookieContainer; 42 request.AllowAutoRedirect = true; 43 request.Method = "POST"; 44 request.Headers.Add("Origin", "http://" + context.Request.UrlReferrer.Host); 45 request.Headers.Add("Accept-Encoding", "gzip, deflate"); 46 request.Headers.Add("Accept-Language", "zh-CN,zh;q=0.8"); 47 request.Headers.Add("Upgrade-Insecure-Requests", "1"); 48 request.Referer = context.Request.UrlReferrer.OriginalString; 49 string boundary = DateTime.Now.Ticks.ToString("X"); // 隨機分隔線 50 request.ContentType = "multipart/form-data;charset=utf-8;boundary=" + boundary; 51 byte[] itemBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n"); 52 byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n"); 53 54 //請求頭部信息 55 StringBuilder sbHeader = new StringBuilder(string.Format("Content-Disposition:form-data;name=\"file\";filename=\"{0}\"\r\nContent-Type:application/octet-stream\r\n\r\n",fileName)); 56 byte[] postHeaderBytes = Encoding.UTF8.GetBytes(sbHeader.ToString()); 57 58 Stream postStream = request.GetRequestStream(); 59 postStream.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length); 60 postStream.Write(postHeaderBytes, 0, postHeaderBytes.Length); 61 postStream.Write(bArr, 0, bArr.Length); 62 postStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length); 63 postStream.Close(); 64 //發送請求並獲取相應回應數據 65 HttpWebResponse response = request.GetResponse() as HttpWebResponse; 66 SetCookie(response,context); 67 68 69 70 } 71 72 73 74 //response是目標伺服器的響應對象,context是返回給瀏覽器的上下文對象 75 void SetCookie(HttpWebResponse response, HttpContext context) 76 { 77 foreach (Cookie cookie in response.Cookies) 78 { 79 if (cookie.Name!=null&&cookie.Name.StartsWith("Picture")) 80 { 81 string result=string.Empty; 82 if (cookie.Value != null && cookie.Value.StartsWith("http://")) 83 { 84 Regex r = new Regex(@"^.*?(?=\|)"); 85 result = r.Match(cookie.Value).Value; 86 } 87 else { 88 result = cookie.Value; 89 } 90 context.Response.Write(result); 91 context.Response.End(); 92 } 93 94 } 95 }View Code
本次遇到的難題主要是解析base64字元串的問題,總是遇到"輸入的不是有效的 Base-64 字元串,因為它包含非 Base-64 字元、兩個以上的填充字"。經過反覆的調整,終於實現了相應的功能。