移動端圖片上傳老失敗

來源:互聯網
上載者:User

標籤:orm   res   繪製   enter   relative   instance   ini   canvas   max   

做移動端開發的時候,form裡面的file後台經常擷取不到,用foemdata也拿不到

找到了一個formdata的指令碼

<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">  <title>移動端圖片壓縮上傳demo</title>  <style>    *{margin: 0;padding: 0;}    li{list-style-type: none;}    a,input{outline: none;-webkit-tap-highlight-color:rgba(0,0,0,0);}    #choose{display: none;}    canvas{width: 100%;border: 1px solid #000000;}    #upload{display: block;margin: 10px;height: 60px;text-align: center;line-height: 60px;border: 1px solid;border-radius: 5px;cursor: pointer;}    .touch{background-color: #ddd;}    .img-list{margin: 10px 5px;}    .img-list li{position: relative;display: inline-block;width: 100px;height: 100px;margin: 5px 5px 20px 5px;border: 1px solid rgb(100,149,198);background: #fff no-repeat center;background-size: cover;}    .progress{position: absolute;width: 100%;height: 20px;line-height: 20px;bottom: 0;left: 0;background-color:rgba(100,149,198,.5);}    .progress span{display: block;width: 0;height: 100%;background-color:rgb(100,149,198);text-align: center;color: #FFF;font-size: 13px;}    .size{position: absolute;width: 100%;height: 15px;line-height: 15px;bottom: -18px;text-align: center;font-size: 13px;color: #666;}    .tips{display: block;text-align:center;font-size: 13px;margin: 10px;color: #999;}    .pic-list{margin: 10px;line-height: 18px;font-size: 13px;}    .pic-list a{display: block;margin: 10px 0;}    .pic-list a img{vertical-align: middle;max-width: 30px;max-height: 30px;margin: -4px 0 0 10px;}  </style></head><body><input type="file" id="choose" accept="image/*" multiple><ul class="img-list"></ul><a id="upload">上傳圖片</a><span class="tips">只允許上傳jpg、png及gif</span><div class="pic-list">  你上傳的圖片(圖片有效期間為1分鐘):</div><script src="/public/jquery-2.1.1.min.js"></script><script>  var filechooser = document.getElementById("choose");  //    用於壓縮圖片的canvas  var canvas = document.createElement("canvas");  var ctx = canvas.getContext(‘2d‘);  //    瓦片canvas  var tCanvas = document.createElement("canvas");  var tctx = tCanvas.getContext("2d");  var maxsize = 100 * 1024;  $("#upload").on("click", function() {        filechooser.click();      })      .on("touchstart", function() {        $(this).addClass("touch")      })      .on("touchend", function() {        $(this).removeClass("touch")      });  filechooser.onchange = function() {    if (!this.files.length) return;    var files = Array.prototype.slice.call(this.files);    if (files.length > 9) {      alert("最多同時只可上傳9張圖片");      return;    }    files.forEach(function(file, i) {      if (!/\/(?:jpeg|png|gif)/i.test(file.type)) return;      var reader = new FileReader();      var li = document.createElement("li");//          擷取圖片大小      var size = file.size / 1024 > 1024 ? (~~(10 * file.size / 1024 / 1024)) / 10 + "MB" : ~~(file.size / 1024) + "KB";      li.innerHTML = ‘<div class="progress"><span></span></div><div class="size">‘ + size + ‘</div>‘;      $(".img-list").append($(li));      reader.onload = function() {        var result = this.result;        var img = new Image();        img.src = result;        $(li).css("background-image", "url(" + result + ")");        //如果圖片大小小於100kb,則直接上傳        if (result.length <= maxsize) {          img = null;          upload(result, file.type, $(li));          return;        }//      圖片載入完畢之後進行壓縮,然後上傳        if (img.complete) {          callback();        } else {          img.onload = callback;        }        function callback() {          var data = compress(img);          upload(data, file.type, $(li));          img = null;        }      };      reader.readAsDataURL(file);    })  };  //    使用canvas對大圖片進行壓縮  function compress(img) {    var initSize = img.src.length;    var width = img.width;    var height = img.height;    //如果圖片大於四百萬像素,計算壓縮比並將大小壓至400萬以下    var ratio;    if ((ratio = width * height / 4000000) > 1) {      ratio = Math.sqrt(ratio);      width /= ratio;      height /= ratio;    } else {      ratio = 1;    }    canvas.width = width;    canvas.height = height;//        鋪底色    ctx.fillStyle = "#fff";    ctx.fillRect(0, 0, canvas.width, canvas.height);    //如果圖片像素大於100萬則使用瓦片繪製    var count;    if ((count = width * height / 1000000) > 1) {      count = ~~(Math.sqrt(count) + 1); //計算要分成多少塊瓦片//            計算每塊瓦片的寬和高      var nw = ~~(width / count);      var nh = ~~(height / count);      tCanvas.width = nw;      tCanvas.height = nh;      for (var i = 0; i < count; i++) {        for (var j = 0; j < count; j++) {          tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh);          ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);        }      }    } else {      ctx.drawImage(img, 0, 0, width, height);    }    //進行最小壓縮    var ndata = canvas.toDataURL(‘image/jpeg‘, 0.1);    console.log(‘壓縮前:‘ + initSize);    console.log(‘壓縮後:‘ + ndata.length);    console.log(‘壓縮率:‘ + ~~(100 * (initSize - ndata.length) / initSize) + "%");    tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;    return ndata;  }  //    圖片上傳,將base64的圖片轉成二進位對象,塞進formdata上傳  function upload(basestr, type, $li) {    var text = window.atob(basestr.split(",")[1]);    var buffer = new Uint8Array(text.length);    var pecent = 0, loop = null;    for (var i = 0; i < text.length; i++) {      buffer[i] = text.charCodeAt(i);    }    var blob = getBlob([buffer], type);    var xhr = new XMLHttpRequest();    var formdata = getFormData();    formdata.append(‘imagefile‘, blob);    xhr.open(‘post‘, ‘/cupload‘);    xhr.onreadystatechange = function() {      if (xhr.readyState == 4 && xhr.status == 200) {        var jsonData = JSON.parse(xhr.responseText);        var imagedata = jsonData[0] || {};        var text = imagedata.path ? ‘上傳成功‘ : ‘上傳失敗‘;        console.log(text + ‘:‘ + imagedata.path);        clearInterval(loop);        //當收到該訊息時上傳完畢        $li.find(".progress span").animate({‘width‘: "100%"}, pecent < 95 ? 200 : 0, function() {          $(this).html(text);        });        if (!imagedata.path) return;        $(".pic-list").append(‘<a href="‘ + imagedata.path + ‘">‘ + imagedata.name + ‘(‘ + imagedata.size + ‘)<img src="‘ + imagedata.path + ‘" /></a>‘);      }    };    //資料發送進度,前50%展示該進度    xhr.upload.addEventListener(‘progress‘, function(e) {      if (loop) return;      pecent = ~~(100 * e.loaded / e.total) / 2;      $li.find(".progress span").css(‘width‘, pecent + "%");      if (pecent == 50) {        mockProgress();      }    }, false);    //資料後50%用類比進度    function mockProgress() {      if (loop) return;      loop = setInterval(function() {        pecent++;        $li.find(".progress span").css(‘width‘, pecent + "%");        if (pecent == 99) {          clearInterval(loop);        }      }, 100)    }    xhr.send(formdata);  }  /**   * 擷取blob對象的相容性寫法   * @param buffer   * @param format   * @returns {*}   */  function getBlob(buffer, format) {    try {      return new Blob(buffer, {type: format});    } catch (e) {      var bb = new (window.BlobBuilder || window.WebKitBlobBuilder || window.MSBlobBuilder);      buffer.forEach(function(buf) {        bb.append(buf);      });      return bb.getBlob(format);    }  }  /**   * 擷取formdata   */  function getFormData() {    var isNeedShim = ~navigator.userAgent.indexOf(‘Android‘)        && ~navigator.vendor.indexOf(‘Google‘)        && !~navigator.userAgent.indexOf(‘Chrome‘)        && navigator.userAgent.match(/AppleWebKit\/(\d+)/).pop() <= 534;    return isNeedShim ? new FormDataShim() : new FormData()  }  /**   * formdata 補丁, 給不支援formdata上傳blob的android機打補丁   * @constructor   */  function FormDataShim() {    console.warn(‘using formdata shim‘);    var o = this,        parts = [],        boundary = Array(21).join(‘-‘) + (+new Date() * (1e16 * Math.random())).toString(36),        oldSend = XMLHttpRequest.prototype.send;    this.append = function(name, value, filename) {      parts.push(‘--‘ + boundary + ‘\r\nContent-Disposition: form-data; name="‘ + name + ‘"‘);      if (value instanceof Blob) {        parts.push(‘; filename="‘ + (filename || ‘blob‘) + ‘"\r\nContent-Type: ‘ + value.type + ‘\r\n\r\n‘);        parts.push(value);      }      else {        parts.push(‘\r\n\r\n‘ + value);      }      parts.push(‘\r\n‘);    };    // Override XHR send()    XMLHttpRequest.prototype.send = function(val) {      var fr,          data,          oXHR = this;      if (val === o) {        // Append the final boundary string        parts.push(‘--‘ + boundary + ‘--\r\n‘);        // Create the blob        data = getBlob(parts);        // Set up and read the blob into an array to be sent        fr = new FileReader();        fr.onload = function() {          oldSend.call(oXHR, fr.result);        };        fr.onerror = function(err) {          throw err;        };        fr.readAsArrayBuffer(data);        // Set the multipart content type and boudary        this.setRequestHeader(‘Content-Type‘, ‘multipart/form-data; boundary=‘ + boundary);        XMLHttpRequest.prototype.send = oldSend;      }      else {        oldSend.call(this, val);      }    };  }</script></body></html>

 

移動端圖片上傳老失敗

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.