你的位置:首页 > Java教程

[Java教程]html5上传图片(一)一跨域上传


       最近开发一个上传图片的模块,传图片的接口不支持跨域上传,并且只支持单张上传,而我们的产品要求要实现多张上传。我搞了一个代理页面,先将图片传到代理页面,然后再通过代理页面传到上传图片接口。虽然这种方式经过一个代理页面会增加消耗的时间,但总算解决了跨域上传的问题。现在粘贴我的代码如下,前端脚本:

 1 (function () { 2   var imgOperate = { 3     operateUrl: "更改图片在数据库中的状态地址", 4     uploadUrl: "代理图片上传地址", 5     DelPicId: '', 6     ddWidth: 0, 7     dlWidth:0, 8     onload: function () { 9       this.initImage(); 10     }, 11     initImage: function () { 12       var et = $('#entrust dd').length; 13       this.ddWidth = $('#entrust dd').width() + 17; 14       this.dlWidth = parseInt(et * this.ddWidth + 160); 15       $('#entrust').css("width", this.dlWidth); 16       this.BindEvent(); 17     }, 18     BindEvent: function () { 19       var _this = this; 20       $("#pic0").on("change", function () { 21         22         _this.uploadFiles(this); 23         24       }); 25    26     }, 27     InserImage:function(urls,dd) 28     { 29       $.post(this.operateUrl, { houseid: houseid, operateType: 1, picStr: urls }, function (data) { 30         data = eval("(" + data + ")"); 31         if (data && data.picIds) 32         { 33           dd.getElementsByTagName("img")[0].setAttribute("housepicid", data.picIds); 34         } 35       }); 36     }, 37     uploadFiles: function (where) { 38       39       var imgLength = $("#entrust dd").length - 1; 40        41       if (imgLength >= 50) 42       { 43         this.ShowMsg("你的图片超过了50张,不能再上传"); 44         return; 45       } 46       if (imgLength + where.files.length > 50) 47       { 48         this.ShowMsg("你选择的图片超过了50张,无法上传,请重新选择"); 49         return; 50       } 51       var _this = this; 52       var radtime = new Date(); 53       var _this = this; 54       var sid = radtime.getTime(); 55       for (var i = 0, successCount=0; i < where.files.length; i++) { 56         var formData = new FormData(); 57         58         formData.append("icoimage",where.files[i]); 59        60         $.ajax({ 61           url:this.uploadUrl+ '?channel=频道&sid=' + sid, 62           type: 'POST', 63           cache: false, 64           data: formData, 65           processData: false, 66           contentType: false 67         }).success(function (res) { 68           var imgsrc = res; 69        if (imgsrc == "-1" || imgsrc == "302" || imgsrc == -1 || imgsrc == 302) { 70                 _this.ShowMsg("上传失败,照片超过10M"); 71               } else if (imgsrc.indexOf("http")!=-1) { 72                   var dd = document.createElement("dd"); 73                   if ($("#entrust dd").length == 1) { 74                     dd.innerHTML = "<div class=\"cver\">封面图</div><a class=\"close\"></a><img src=\"" + imgsrc + "\" housepicid=\"\">"; 75                   } else { 76                     dd.innerHTML = "<a class=\"close\"></a><img src=\"" + imgsrc + "\" housepicid=\"\">"; 77                    } 78                   document.getElementById("entrust").appendChild(dd); 79                   _this.dlWidth += _this.ddWidth + 17; 80                   $('#entrust').css("width", _this.dlWidth); 81                    _this.InserImage(imgsrc, dd); 82                   successCount++; 83                   _this.ShowMsg("正在上传第" + i + "张图片"); 84                     } 85        if (i == where.files.length) { 86          if (successCount > 0) { 87            _this.ShowMsg("成功上传" + successCount + ",可继续上传新照片"); 88           } 89        } else { 90          _this.ShowMsg("上传失败"); 91         } 92  93         }) 94       } 95  96     }, 97     ShowMsg: function (text, mymethod) { 98       var radtime = new Date(); 99       var sid = radtime.getTime();100       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>";101 102       $(msg_div).appendTo("body");103       var _this = this;104       setTimeout(function () {105         var d = 0.5;106         var m = document.getElementById("div_msg"+sid);107         m.style.webkitTransition = '-webkit-transform ' + d + 's ease-in, opacity ' + d + 's ease-in';108         m.style.opacity = '0';109         setTimeout(_this.RemoveNode(m), 500);110       }, 500);111     },112     RemoveNode: function (m) {113       m.parentNode.removeChild(m);114     }115 116   }117 118   imgOperate.onload();119   window.imgOperate = imgOperate;120  121 122 123 })();

前端脚本代码

代理服务器代码:

   public override void ProcessRequest(HttpContext context)    {      //获取目标站点地址      String target = "图片服务器地址";      string sid = context.Request["sid"];      target = string.Format("{0}?city=&channel=频道&sid={1}&backurl=",target,sid);   if(context.Request.Files.Count>0)      {        var file = context.Request.Files[0];        HttpWebRequest request = WebRequest.Create(target) as HttpWebRequest;        CookieContainer cookieContainer = new CookieContainer();        request.CookieContainer = cookieContainer;        request.AllowAutoRedirect = true;        request.Method = "POST";        request.Headers.Add("Origin", "http://" + context.Request.UrlReferrer.Host);        request.Headers.Add("Accept-Encoding", "gzip, deflate");        request.Headers.Add("Accept-Language", "zh-CN,zh;q=0.8");        request.Headers.Add("Upgrade-Insecure-Requests", "1");        request.Referer = context.Request.UrlReferrer.OriginalString;        string boundary = DateTime.Now.Ticks.ToString("X"); // 随机分隔线        request.ContentType = "multipart/form-data;charset=utf-8;boundary=" + boundary;        byte[] itemBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");        byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");               //请求头部信息         StringBuilder sbHeader = new StringBuilder(string.Format("Content-Disposition:form-data;name=\"file\";filename=\"{0}\"\r\nContent-Type:application/octet-stream\r\n\r\n", file.FileName));        byte[] postHeaderBytes = Encoding.UTF8.GetBytes(sbHeader.ToString());        //FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);        byte[] bArr = new byte[file.InputStream.Length];        file.InputStream.Read(bArr, 0, bArr.Length);        file.InputStream.Close();        Stream postStream = request.GetRequestStream();        postStream.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length);        postStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);        postStream.Write(bArr, 0, bArr.Length);        postStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);        postStream.Close();        //发送请求并获取相应回应数据        HttpWebResponse response = request.GetResponse() as HttpWebResponse;        SetCookie(response,context);      }          } //response是目标服务器的响应对象,context是返回给浏览器的上下文对象    void SetCookie(HttpWebResponse response, HttpContext context)    {      foreach (Cookie cookie in response.Cookies)      {        if (cookie.Name!=null&&cookie.Name.StartsWith("img"))        {          string result=string.Empty;          if (cookie.Value != null && cookie.Value.StartsWith("http://"))          {            Regex r = new Regex(@"^.*?(?=\|)");            result = r.Match(cookie.Value).Value;          }          else {            result = cookie.Value;          }          context.Response.Write(result);          context.Response.End();        }            }    }

          因为图片服务器返回的地址是种在cookie当中的,因此代理服务器中我将相应cookie的地址接收予以返回。在开发该功能时我遇到了很多问题,图片接口又不配合,后来自己模拟相应服务器的接口上传,才发现代理中并没有将文件传上去。经过比较修改,最后才上传成功。