解决微信内嵌浏览器无法响应上传文件(图片)

  • 我尝试过的办法
    •        首先是<input type=”file”>,这是我们最容易,同时也是最先用的,应该也是我试过那么多的插件都是用这个,这个只有在部分手机的微信版本上会显示upload disable,大部分手机微信还是支持的,但是做完我们会发现我们的微信可以选择文件,但是上传不了,百度了一下很多人说这个被腾讯给“阉割”掉了,一开始我也是这么觉得,所以就放弃了选择这个,后来发现,腾讯“阉割”掉了的不是<input type=”file”>,而是你上传往服务器发请求的那一块,具体怎么解释我是新手,真心不造怎么说,后面会再说,希望知道这个原理的能和我说明一下。
    •        放弃了<input type=”file”>,我们工作室的师兄就推荐我一款插件,叫Uploadify,这款插件在它的官网上面有两种版本,一种是flash(免费),一种是html5(收费),不过也有大牛把html5的版本模仿了出来,网上找得到。首先是flash吧,这个也是另外一篇博文里博主推荐大家的方法(原文地址:http://blog.csdn.net/zz880329/article/details/12652063),我就尝试了一下,发现使用flash实现上传的话,选择文件的“样式”变了,变成了flash的选择文件,大家自己试过的话应该就会发现,flash选择文件的方式你看到的只有文件名,你都不知道自己要选哪张图片好,而且好像还需要手机有flash支持,所以这个flash被我放弃了。然后是html5的版本,打开demo的代码,上面确实没有了<input type=”file”>,但是实际运行起来,在网页还是用的是了<input type=”file”>,实际放到微信上好像也是行不通,后来也就放弃了。
    •        后面又看到一篇介绍各种HTML5的上传插件的博文,然后又是像无头苍蝇那样各种尝试,最终只保留下了其中一种我觉得是最可行的,但是好像兼容性各方面还有待优化,后面我的第二种可行办法我会再介绍它的,希望大家都说下各自的理解吧,还有好多方面我都不太懂。
  • 第一种可行的js插件
    •        尝试过很多插件之后,基本都以失败告终。不过好像每次写代码都很幸运,我舍友在微信上找到一个网站是有实现相关功能的,然后我就去找到那个网站研究他们的上传插件,发现使用的插件我之前没有尝试过,于是就找到了这个插件并且成功实现功能,插件叫ajaxfileupload.js
    • // JavaScript Document
      jQuery.extend({


          createUploadIframe: function(id, uri)
       {
         //create frame
                  var frameId = 'jUploadFrame' + id;
                  
                  if(window.ActiveXObject) {
                      var io = document.createElement('<iframe id="' + frameId + '" name="' + frameId + '" />');
                      if(typeof uri== 'boolean'){
                          io.src = 'javascript:false';
                      }
                      else if(typeof uri== 'string'){
                          io.src = uri;
                      }
                  }
                  else {
                      var io = document.createElement('iframe');
                      io.id = frameId;
                      io.name = frameId;
                  }
                  io.style.position = 'absolute';
                  io.style.top = '-1000px';
                  io.style.left = '-1000px';


                  document.body.appendChild(io);


                  return io;   
          },
          createUploadForm: function(id, fileElementId)
       {
        //create form 
        var formId = 'jUploadForm' + id;
        var fileId = 'jUploadFile' + id;
        var form = jQuery('<form  action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>'); 
        var oldElement = jQuery('#' + fileElementId);
        var newElement = jQuery(oldElement).clone();
        jQuery(oldElement).attr('id', fileId);
        jQuery(oldElement).before(newElement);
        jQuery(oldElement).appendTo(form);
        //set attributes
        jQuery(form).css('position', 'absolute');
        jQuery(form).css('top', '-1200px');
        jQuery(form).css('left', '-1200px');
        jQuery(form).appendTo('body');  
        return form;
          },


          ajaxFileUpload: function(s) {
              // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout  
              s = jQuery.extend({}, jQuery.ajaxSettings, s);
              var id = s.fileElementId;        
        var form = jQuery.createUploadForm(id, s.fileElementId);
        var io = jQuery.createUploadIframe(id, s.secureuri);
        var frameId = 'jUploadFrame' + id;
        var formId = 'jUploadForm' + id;  
              
              if( s.global && ! jQuery.active++ )
        {
         // Watch for a new set of requests
         jQuery.event.trigger( "ajaxStart" );
        }            
              var requestDone = false;
              // Create the request object
              var xml = {};   
              if( s.global )
              {
               jQuery.event.trigger("ajaxSend", [xml, s]);
              }            
              
              var uploadCallback = function(isTimeout)
        {  
         // Wait for a response to come back 
         var io = document.getElementById(frameId);
                  try 
         {    
          if(io.contentWindow)
          {
            xml.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null;
                        xml.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;
            
          }else if(io.contentDocument)
          {
            xml.responseText = io.contentDocument.document.body?io.contentDocument.document.body.innerHTML:null;
                       xml.responseXML = io.contentDocument.document.XMLDocument?io.contentDocument.document.XMLDocument:io.contentDocument.document;
          }      
                  }catch(e)
         {
          jQuery.handleError(s, xml, null, e);
         }
                  if( xml || isTimeout == "timeout") 
         {    
                      requestDone = true;
                      var status;
                      try {
                          status = isTimeout != "timeout" ? "success" : "error";
                          // Make sure that the request was successful or notmodified
                          if( status != "error" )
           {
                              // process the data (runs the xml through httpData regardless of callback)
                              var data = jQuery.uploadHttpData( xml, s.dataType );                        
                              if( s.success )
                              {
             // ifa local callback was specified, fire it and pass it the data
                               s.success( data, status );
                              };                 
                              if( s.global )
                              {
             // Fire the global callback
                               jQuery.event.trigger( "ajaxSuccess", [xml, s] );
                              };                            
                          } else
                          {
                           jQuery.handleError(s, xml, status);
                          }
                              
                      } catch(e) 
          {
                          status = "error";
                          jQuery.handleError(s, xml, status, e);
                      };                
                      if( s.global )
                      {
           // The request was completed
                       jQuery.event.trigger( "ajaxComplete", [xml, s] );
                      };
                          


                      // Handle the global AJAX counter
                      if(s.global && ! --jQuery.active)
                      {
                       jQuery.event.trigger("ajaxStop");
                      };
                      if(s.complete)
                      {
                        s.complete(xml, status);
                      } ;                 


                      jQuery(io).unbind();


                      setTimeout(function()
               { try 
                {
                 jQuery(io).remove();
                 jQuery(form).remove(); 
                 
                } catch(e) 
                {
                 jQuery.handleError(s, xml, null, e);
                }         


               }, 100);


                      xml = null;


                  };
              }
              // Timeout checker
              if( s.timeout > 0 ) 
        {
                  setTimeout(function(){
                      
                      if( !requestDone )
                      {
           // Check to see ifthe request is still happening
                       uploadCallback( "timeout" );
                      }
                      
                  }, s.timeout);
              }
              try 
        {
         var form = jQuery('#' + formId);
         jQuery(form).attr('action', s.url);
         jQuery(form).attr('method', 'POST');
         jQuery(form).attr('target', frameId);
                  if(form.encoding)
         {
                      form.encoding = 'multipart/form-data';    
                  }
                  else
         {    
                      form.enctype = 'multipart/form-data';
                  }   
                  jQuery(form).submit();


              } catch(e) 
        {   
                  jQuery.handleError(s, xml, null, e);
              }
              if(window.attachEvent){
                  document.getElementById(frameId).attachEvent('onload', uploadCallback);
              }
              else{
                  document.getElementById(frameId).addEventListener('load', uploadCallback, false);
              }   
              return {abort: function () {}}; 


          },


          uploadHttpData: function( r, type ) {
              var data = !type;
              data = type == "xml" || data ? r.responseXML : r.responseText;
              // ifthe type is "script", eval it in global context
              if( type == "script" )
              {
               jQuery.globalEval( data );
              }
                  
              // Get the JavaScript object, ifJSON is used.
              if( type == "json" )
              {
               eval( "data = " + data );
              }
                  
              // evaluate scripts within html
              if( type == "html" )
              {
               jQuery("<div>").html(data).evalScripts();
              }
                  
              return data;
          }
      });
  • 前端代码:
  • <!DOCTYPE html>
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Insert title here</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, minimum-scale=1, maximum-scale=1">
        <script src="jquery-1.7.1.js" type="text/javascript"></script>
        <script src="ajaxfileupload.js" type="text/javascript"></script>
        <script type="text/javascript">
            function ajaxFileUpload() {
                $.ajaxFileUpload
                (
                    {
                        url: 'upload.aspx', //用于文件上传的服务器端请求地址
                        secureuri: false, //一般设置为false
                        fileElementId: 'file', //文件上传空间的id属性  <input type="file" id="file" name="file" />
                        dataType: 'json', //返回值类型 一般设置为json
                        success: function (data, status)  //服务器成功响应处理函数
                        {
                            $("#img1").attr("src", data.imgurl);
                            if (typeof (data.error) != 'undefined') {
                                if (data.error != '') {
                                    alert(data.error);
                                } else {
                                    alert(data.msg);
                                }
                            }
                        },
                        error: function (data, status, e)//服务器响应失败处理函数
                        {
                            alert(e);
                        }
                    }
                )
                return false;
            }
        </script>
    </head>
    <body>
        <input type="file" id="file" name="file"  value="上传" accept="image/*;capture=camera"  οnchange="ajaxFileUpload()"/>
        <p><img id="img1" alt="上传成功啦" src="" /></p>
    
    </body>
    </html>

但是现在微信6.2以后,也不好使了

第二种可行的办法,仅限用于图片,其他类型文件我还没尝试
  • 接下来是第二种可行的办法,也是在找控件的过程中发现的,感觉很棒,我在三星的微信上试过可以实现上传,但是在魅族上页面还是出错了,之后由于第一种方法可以兼容,于是就采用了第一种,没有对第二种进行深究了,不过还是分享一下。它的原理就是把你点击选择完图片后,用js将你选择的图片转为base64格式的数据,而且还能实现使用js对图片进行压缩后保存下压缩后的base64格式的字符串数据,而我们只需要把这串字符串发送到后台,然后在后台将base64格式的数据转为图片就容易啦,这样,腾讯也抓不了。

  • 前台代码,我跟原作者代码有修改了一点,因为发现发送到后台base64转图片的时候,base64编码不能带上“文件头”(/^data:base64,/),还有就是加上了压缩图片所需要修改的参数的位置,这里默认压缩为100*100。(原作者好腻害的赶脚)。

  • <!doctype html>
    <html>
    <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
    <title>图片压缩</title>
        <script src="jquery-1.7.1.js" type="text/javascript"></script>
    <style>
    body { margin:0; padding:0; }
    html { font-size:62.5%; }
    
    .imgzip { padding:1em; }
    .imgzip .itm { padding-bottom:1em; word-break:break-all; font-size:1.2rem; line-height:1.5em; }
    .imgzip .itm .tit { margin-bottom:.5em; background-color:#e71446; color:#FFF; padding:.5rem 1rem; border-radius:3px; }
    .imgzip .itm .cnt { padding:1rem; }
    .imgzip .itm .cnt img { display:block; max-width:100%; }
    .imgzip textarea { width:100%; height:20em; }
    </style>
    </head>
    
    <body>
    <input type="file" accept="image/*;capture=camera" class="input">
    <input type="button" value="上传" οnclick="upload();" />
    <div class="imgzip"></div>
    <script>
        document.addEventListener('DOMContentLoaded', init, false);
    
        function init() {
            var u = new UploadPic();
            u.init({
                input: document.querySelector('.input'),
                callback: function (base64) {
                    var html = '';
    
                    html = '<div class="itm"><div class="tit">图片名称:</div><div class="cnt" id="name">' + this.fileName + '</div></div>'
               + '<div class="itm"><div class="tit">原始大小:</div><div class="cnt">' + (this.fileSize / 1024).toFixed(2) + 'KB<\/div><\/div>'
               + '<div class="itm"><div class="tit">编码大小:</div><div class="cnt">' + (base64.length / 1024).toFixed(2) + 'KB<\/div><\/div>'
               + '<div class="itm"><div class="tit">原始尺寸:</div><div class="cnt">' + this.tw + 'px * ' + this.th + 'px<\/div><\/div>'
               + '<div class="itm"><div class="tit">编码尺寸:</div><div class="cnt">' + this.sw + 'px * ' + this.sh + 'px<\/div><\/div>'
               + '<div class="itm"><div class="tit">图片预览:</div><div class="cnt"><img src="' + base64 + '"><\/div><\/div>'
               + '<div class="itm"><div class="tit">Base64编码:</div><div class="cnt"><textarea id="base64">' + this.noHead + '<\/textarea><\/div><\/div>';
    
                    document.querySelector('.imgzip').innerHTML = html;
                },
                loading: function () {
                    document.querySelector('.imgzip').innerHTML = '读取中,请稍候...';
                }
            });
        }
    
        function UploadPic() {
            this.sw = 0;
            this.sh = 0;
            this.tw = 0;
            this.th = 0;
            this.scale = 0;
            this.maxWidth = 0;
            this.maxHeight = 0;
            this.maxSize = 0;
            this.fileSize = 0;
            this.fileDate = null;
            this.fileType = '';
            this.fileName = '';
            this.input = null;
            this.canvas = null;
            this.mime = {};
            this.type = '';
            this.callback = function () { };
            this.loading = function () { };
            this.noHead = "";
        }
    
        UploadPic.prototype.init = function (options) {
            this.maxWidth = options.maxWidth || 800;
            this.maxHeight = options.maxHeight || 600;
            this.maxSize = options.maxSize || 3 * 1024 * 1024;
            this.input = options.input;
            this.mime = { 'png': 'image/png', 'jpg': 'image/jpeg', 'jpeg': 'image/jpeg', 'bmp': 'image/bmp' };
            this.callback = options.callback || function () { };
            this.loading = options.loading || function () { };
    
            this._addEvent();
        };
    
        /**
        * @description 绑定事件
        * @param {Object} elm 元素
        * @param {Function} fn 绑定函数
        */
        UploadPic.prototype._addEvent = function () {
            var _this = this;
    
            function tmpSelectFile(ev) {
                _this._handelSelectFile(ev);
            }
    
            this.input.addEventListener('change', tmpSelectFile, false);
        };
    
        /**
        * @description 绑定事件
        * @param {Object} elm 元素
        * @param {Function} fn 绑定函数
        */
        UploadPic.prototype._handelSelectFile = function (ev) {
            var file = ev.target.files[0];
    
            this.type = file.type
    
            // 如果没有文件类型,则通过后缀名判断(解决微信及360浏览器无法获取图片类型问题)
            if (!this.type) {
                this.type = this.mime[file.name.match(/\.([^\.]+)$/i)[1]];
            }
    
            if (!/image.(png|jpg|jpeg|bmp)/.test(this.type)) {
                alert('选择的文件类型不是图片');
                return;
            }
    
            if (file.size > this.maxSize) {
                alert('选择文件大于' + this.maxSize / 1024 / 1024 + 'M,请重新选择');
                return;
            }
    
            this.fileName = file.name;
            this.fileSize = file.size;
            this.fileType = this.type;
            this.fileDate = file.lastModifiedDate;
    
            this._readImage(file);
        };
    
        /**
        * @description 读取图片文件
        * @param {Object} image 图片文件
        */
        UploadPic.prototype._readImage = function (file) {
            var _this = this;
    
            function tmpCreateImage(uri) {
                _this._createImage(uri);
            }
    
            this.loading();
    
            this._getURI(file, tmpCreateImage);
        };
    
        /**
        * @description 通过文件获得URI
        * @param {Object} file 文件
        * @param {Function} callback 回调函数,返回文件对应URI
        * return {Bool} 返回false
        */
        UploadPic.prototype._getURI = function (file, callback) {
            var reader = new FileReader();
            var _this = this;
            //
            function tmpLoad() {
                // 头不带图片格式,需填写格式
                var re = /^data:base64,/;
                var ret = this.result + '';
                if (re.test(ret)) ret = ret.replace(re, 'data:' + _this.mime[_this.fileType] + ';base64,');
                
                //此处为自己加上的去掉base64不带“头”的判断
                if (ret.indexOf(";base64,") >= 0) {
                    var num = ret.indexOf(";base64,");
                    num = parseInt(num) + 8;
                    _this.noHead = ret.substring(num);
                }
                
                callback && callback(ret);
            }
    
            reader.onload = tmpLoad;
    
            reader.readAsDataURL(file);
    
            return false;
        };
    
        /**
        * @description 创建图片
        * @param {Object} image 图片文件
        */
        UploadPic.prototype._createImage = function (uri) {
            var img = new Image();
            var _this = this;
    
            function tmpLoad() {
                _this._drawImage(this);
            }
    
            img.onload = tmpLoad;
    
            img.src = uri;
        };
    
        /**
        * @description 创建Canvas将图片画至其中,并获得压缩后的文件
        * @param {Object} img 图片文件
        * @param {Number} width 图片最大宽度
        * @param {Number} height 图片最大高度
        * @param {Function} callback 回调函数,参数为图片base64编码
        * return {Object} 返回压缩后的图片
        */
        UploadPic.prototype._drawImage = function (img, callback) {
            //        this.sw = img.width;
            //        this.sh = img.height;
            //如果不需要压缩可将上面注释与下面的更换;
            this.tw = img.width;
            this.th = img.height;
            this.sw = 100;
            this.sh = 100;
    
    
            this.scale = (this.tw / this.th).toFixed(2);
    
            if (this.sw > this.maxWidth) {
                this.sw = this.maxWidth;
                this.sh = Math.round(this.sw / this.scale);
            }
    
            if (this.sh > this.maxHeight) {
                this.sh = this.maxHeight;
                this.sw = Math.round(this.sh * this.scale);
            }
    
            this.canvas = document.createElement('canvas');
            var ctx = this.canvas.getContext('2d');
    
            this.canvas.width = this.sw;
            this.canvas.height = this.sh;
    
            ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, this.sw, this.sh);
    
            this.callback(this.canvas.toDataURL(this.type));
    
            ctx.clearRect(0, 0, this.tw, this.th);
            this.canvas.width = 0;
            this.canvas.height = 0;
            this.canvas = null;
        };
        function upload() {
            var base64 = $("#base64").val();
            var name = $("#name").text();
            $.ajax(
            {
                type: "post",
                url: "Upload.ashx",
                data: {
                    base64: base64,
                    name: name
                },
                async: true,
                success: function fun(rt) {
                    alert(rt);
                }
    
            });
        };
    </script>
    </body>
    </html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值