JS 從剪貼板上傳圖片

    用Ubuntu兩年多了,習慣了Ubuntu的操做感受比WIN用起來還爽,就一點不爽,生態應用不多,好多WIN上好用的軟件在Ubuntu找不到的,但願之後的軟件能夠作到一次編譯全平臺通用. 即便用上Wine有的軟件應用也存在兼容性問題.好比QQ,Photoshop,微信,旺旺.javascript

因此,在Ubuntu使用過程當中,習慣了用web來訪問,凡事web-Application統統喜歡.php

微信和釘釘常常用,不喜歡wine安裝的應用,就直接網頁版微信,網頁版釘釘,發現好YI功能,當我截圖複製到剪貼板後,能夠直接Ctrl+V在網頁版微信,釘釘粘貼,不用在把圖片先保存在電腦上,再選擇發送文件這麼複雜.html

    

 

而後呢,命題就出來了,如何作到從剪貼板獲取圖片併發送圖片呢?java

paste剪貼板事件

onpaste 事件在用戶向元素中粘貼文本時觸發。web

有三種方式能夠在元素中粘貼內容:json

  • 按下 CTRL + V
  • 從瀏覽器的編輯菜單中選擇 "Paste(粘貼)"
  • 右擊鼠標按鈕在上下文菜單中選擇 "Paste(粘貼)" 命令

參考:https://www.w3cschool.cn/jsref/event-onpaste.htmlcanvas

綁定的元素不必定是input,普通的div也是能夠綁定的,若是是給document綁定了,就至關於全局了,任什麼時候候的粘貼操做都會觸發。數組

粘貼事件提供了一個clipboardData的屬性,若是該屬性有items屬性,那麼就能夠查看items中是否有圖片類型的數據了。瀏覽器

clipboardData介紹微信

介紹一下clipboardData對象,它其實是一個DataTransfer類型的對象,DataTransfer是拖動產生的一個對象,但實際上粘貼事件也是它。

clipboardData的屬性介紹

屬性 類型 說明
dropEffect String 默認是 none
effectAllowed String 默認是 uninitialized
files FileList 粘貼操做爲空List
items DataTransferItemList 剪切板中的各項數據
types Array 剪切板中的數據類型 該屬性在Safari下比較混亂

items介紹

items是一個DataTransferItemList對象,天然裏面都是DataTransferItem類型的數據了。

items屬性

itemsDataTransferItem有兩個屬性kindtype

屬性 說明
kind 通常爲string或者file
type 具體的數據類型,例如具體是哪一種類型字符串或者哪一種類型的文件,即MIME-Type

items方法

方法 參數 說明
getAsFile 若是kindfile,能夠用該方法獲取到文件
getAsString 回調函數 若是kindstring,能夠用該方法獲取到字符串,字符串須要用回調函數獲得,回調函數的第一個參數就是剪切板中的字符串
 
在原型上還有一些其餘方法,不過在處理剪切板操做的時候通常用不到了。

types介紹

通常types中常見的值有

說明
text/plain 普通字符串
text/html 帶有樣式的html
Files 文件(例如剪切板中的數據)

以上介紹COPY來自: https://www.jb51.net/article/123071.htm

 

FileReader對象

FileReader 對象容許Web應用程序異步讀取存儲在用戶計算機上的文件(或原始數據緩衝區)的內容,使用 File 或 Blob 對象指定要讀取的文件或數據。其中File對象能夠是來自用戶在一個<input>元素上選擇文件後返回的FileList對象,也能夠來自拖放操做生成的 DataTransfer對象,還能夠是來自在一個HTMLCanvasElement上執行mozGetAsFile()方法後返回結果。

事件處理

FileReader.onload處理load事件。該事件在讀取操做完成時觸發。

FileReader.onloadend處理loadend事件。該事件在讀取操做結束時(要麼成功,要麼失敗)觸發。

方法

FileReader.readAsDataURL()開始讀取指定的Blob中的內容。一旦完成,result屬性中將包含一個data: URL格式的字符串以表示所讀取文件的內容。

readAsDataURL: 該方法會讀取指定的 Blob 或 File 對象。讀取操做完成的時候,readyState 會變成已完成(DONE),並觸發 loadend 事件,同時 result 屬性將包含一個data:URL格式的字符串(base64編碼)以表示所讀取文件的內容。

示例: https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader/readAsDataURL

function previewFile() {
  var preview = document.querySelector('img');
  var file    = document.querySelector('input[type=file]').files[0];
  var reader  = new FileReader();

  reader.addEventListener("load", function () {
    preview.src = reader.result;
  }, false);

  if (file) {
    reader.readAsDataURL(file);
  }
}

 

來自:https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader

 

base64數據轉blob二進制

請看昨日文章:

JS 實現blob與base64互轉

/**
     * base64  to blob二進制
     */
    function dataURItoBlob(dataURI) {
        var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; // mime類型
        var byteString = atob(dataURI.split(',')[1]); //base64 解碼
        var arrayBuffer = new ArrayBuffer(byteString.length); //建立緩衝數組
        var intArray = new Uint8Array(arrayBuffer); //建立視圖

        for (var i = 0; i < byteString.length; i++) {
            intArray[i] = byteString.charCodeAt(i);
        }
        return new Blob([intArray], {type: mimeString});
    }

 

呈上仿製代碼

ok,以上須要的事件, FileReader對象操做,base64數據轉換都有了,那咱們就直接上代碼.

ImageClipboard.html

<div id="box"></div>
<script type="text/javascript">


// window.addEventListener('paste', pasteHandler);   pasteHandler= fun...
    window.addEventListener('paste', function (e) {
        var items;
        if (e.clipboardData && e.clipboardData.items) {
            items = e.clipboardData.items;
            if (items) {
                items = Array.prototype.filter.call(items, function (element) {
                    return element.type.indexOf("image") >= 0;
                });

                Array.prototype.forEach.call(items, function (item) {
                    var blob = item.getAsFile();
                    var reader = new FileReader();
                    reader.onloadend = function (event) {
                        var imgBase64 = event.target.result;  //    event.target.result.split(",")  [0]=data:image/png;base64  [1]=data
                        console.log(imgBase64);  // base64
                        var dataURI = imgBase64;
                        var blob = dataURItoBlob(dataURI); // blob
                        console.log(blob);
                        uploadImg(blob);

                    };
                    reader.readAsDataURL(blob);

                });
            }
        }
    });


    /**
     * base64  to blob二進制
     */
    function dataURItoBlob(dataURI) {
        var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; // mime類型
        var byteString = atob(dataURI.split(',')[1]); //base64 解碼
        var arrayBuffer = new ArrayBuffer(byteString.length); //建立緩衝數組
        var intArray = new Uint8Array(arrayBuffer); //建立視圖

        for (var i = 0; i < byteString.length; i++) {
            intArray[i] = byteString.charCodeAt(i);
        }
        return new Blob([intArray], {type: mimeString});
    }


    /**
     * 上傳圖片 FormData
     */
    function uploadImg(file) {
        var formData = new FormData();
        formData.append('my-image-file', file);
        formData.append('username', 'myfile');  // 添加自定義數據

        var xhr = new XMLHttpRequest();
        xhr.open('POST', '/html/upload-ser.php');
        xhr.onload = function () {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    var data = JSON.parse(xhr.responseText), tarBox = document.getElementById('box');
                    if (data.id == 1) {
                        var img = document.createElement('img');
                        img.className = 'my_img';
                        img.src = data.src;
                        tarBox.appendChild(img);

                        return 'aaa';
                    } else {
                        alert(data.msg);
                    }
                } else {
                    console.log(xhr.statusText);
                }
            }
        };
        xhr.onerror = function (e) {
            console.log(xhr.statusText);
        }
        xhr.send(formData);
    }
</script>

 

服務端upload-ser.php

<?php

//print_r($_POST);
//print_r($_FILES);

$file = $_FILES['my-image-file'];
if ($file['error'] == 0) {
    define('ROOT', __DIR__);
    if (is_uploaded_file($file['tmp_name'])) {
        $ext = explode('/', $file['type'])[1];
        $filename = "{$file['name']}_" . date("ymdHis") . ".{$ext}";
        $mu = move_uploaded_file($file["tmp_name"], ROOT . "/upload/" . $filename);
        if ($mu) {
            exit(json_encode(['id' => 1, 'src' => 'upload/' . $filename]));
        } else {
            exit(json_encode(['id' => 2, 'msg' => 'move file fail']));
        }
    } else {
        exit(json_encode(['id' => 2, 'msg' => 'failed no post']));
    }
} else {
    exit(json_encode(['id' => 2, 'msg' => $file['error']]));
}

在頁面中,咱們直接Ctrl+V後, 能夠先經過打印POST和FILES看下數據

username 是自定義的post數據,my-image-file是file數據.

console.log打印:

經過xhr返回callback獲得上傳後的信息

 

查看上傳的目錄

 GIF

相關文章
相關標籤/搜索