File API

ES5 推出了一系列的 API:ajax

  • BLOB (二進制大對象)
  • File (文件接口,基於 BLOB,可是增長了文件相關的方法,好比路徑,大小)
  • FileList (藉助 <input type="file">,來獲取硬盤文件的一個接口)
  • FileReader
  • URL

1 Simple APIs

// 第一步,獲取 input
var fileInput = document.getElementById("myfile");

// 第二步,經過 input 獲取 FileList
var fileList = fileInput.files;

// 第三步,經過 FileList 獲取某個文件的對象
var file = fileList[0];

// 簡單來講,獲取 File 對象就是:
file = document.getElementById('myfile').files[0];

一個圖片 <img src="" > 的 src 能夠使下面三個之一:canvas

  1. 文件在操做系統中的路徑
  2. DataURL 數據,用 Base64 編碼,將二進制文件進行加密的過程,而後就能夠使用這字符串來表示二進制文件了
  3. ObjectURL,它是咱們須要使用的文件的一個引用字符串而已,格式爲 blob:http://localhsot:8080/a3b05b0e-bd18-4b53-b6b8-0b345e9aebdb

2 Preview Demo

使用 ObjectURL:服務器

myfile.onchange = function () {
    var imgUrl = URL.createObjectURL(myfile.files[0]);
    myimg.src = imgUrl;
    myimg.onload = () => URL.revokeObjectURL(imgUrl);
};

3 Compress and Upload with AJAX

function shangchuantupian() {
    // 1. 獲取圖片的數據
    // 2. 校驗大小,若是超過尺寸,那麼對其進行壓縮
    // 3. 加上你的水印
    // 4. 調用 ajax 方式,將其發送到服務器

    var canvas = document.createElement("canvas");

    var image = new Image();
    var imgUrl = URL.createObjectURL(myfile.files[0]);
    image.src = imgUrl;

    image.onload = () => {
        URL.revokeObjectURL(imgUrl);

        canvas.width = image.width / 2;
        canvas.height = image.height / 2;

        var ctx = canvas.getContext('2d');
        ctx.drawImage(image, 0, 0, image.width / 2, image.height / 2);
        ctx.fillText("nf147", image.width / 2 - 20, image.height / 2 - 20);

        canvas.toBlob(function (b) {
            var fd = new FormData();
            fd.append("fff", b);

            fetch("/myupload", {
                method: 'post',
                body: fd
            }).then(resp => resp.body);
        }, "image/jpeg");
    };
}

4 Compress and Upload [version 2]

HTML:app

<style>
 #myimg {
     border: 3px solid gray;
     border-radius: 5px;
     position: absolute;
     top: 0;
     left: 0;
 }

 #mymask {
     position: absolute;
     top: 0;
     left: 0;
 }
</style>



<div class="container">
    <div style="margin-top: 2em;">
        <input type="file" id="myfile" style="display: none"> <!-- 選擇文件後,要預覽 -->
        <button class="btn btn-primary" onclick="myfile.click()">選擇圖片</button>
        <button class="btn btn-primary" onclick="clickMe()">上傳圖片</button>
    </div>

    <div style="position: relative">
        <img src="" id="myimg" title="暫時沒有上傳" width="200" height="200"/>
        <canvas id="mymask" width="200" height="200">不支持canvas</canvas>
    </div>
</div>

JS:post

var ctx;

myfile.onchange = () => { // 預覽圖片
    var imgUrl = URL.createObjectURL(event.target.files[0]);
    myimg.src = imgUrl;
    myimg.onload = () => URL.revokeObjectURL(imgUrl);
};

function clickMe() {
    compressImgWithCanvas(myfile.files[0], uploadWithAJAX);
    // uploadWithAJAX(myfile.files[0]);

}

/**
 * 壓縮圖片,而後執行某些任務
 */
function compressImgWithCanvas(blob, taskCallback) {
    console.log("bbb");
    var rat = 2;
    var w = myimg.naturalWidth / rat, h = myimg.naturalHeight / rat;

    var canvas = document.createElement("canvas");
    canvas.width = w;
    canvas.height = h;

    var ctx = canvas.getContext('2d');
    ctx.drawImage(myimg, 0, 0, w, h);
    ctx.fillText("nf147", w - 20, h - 20);

    canvas.toBlob(taskCallback, "image/jpeg");
}

/**
 * 更新預覽進度
 */
function refreshProgress(r) {
    if (!ctx) ctx = mymask.getContext('2d');
    ctx.save();
    ctx.clearRect(0, 0, 200, 200);
    ctx.globalAlpha = 0.6;
    ctx.fillRect(0, (1 - r) * 200, 200, 200);
    ctx.globalAlpha = 1;
    ctx.fillStyle = "white";
    ctx.font = "20px 微軟雅黑";
    ctx.fillText(r * 100 + '%', 80, 180);
    ctx.restore();
}

/**
 * 經過 AJAX 上傳 blob 類型的文件
 * @param blob
 */
function uploadWithAJAX(blob) {
    var fd = new FormData();
    fd.append("fff", blob);

    $.ajax({
        method: 'post',
        url: "/myupload",
        cache: false,
        contentType: false,
        data: fd,
        processData: false,
        xhr: () => {
            var xhr = $.ajaxSettings.xhr();
            xhr.upload.onprogress = (ev) => {
                refreshProgress(ev.loaded / ev.total);
            };
            return xhr;
        }
    }).done(console.log)
        .fail((xhr, staus, err) => console.error(xhr, staus, err));
}
相關文章
相關標籤/搜索