1. 程式人生 > >從剪下板貼上圖片上傳

從剪下板貼上圖片上傳

一個需求:讓使用者使用剪下板來貼上圖片(而不是將圖片儲存到本地,然後再選取檔案上傳)

fakepath是什麼鬼

今天做圖片上傳時發現,不論是什麼路徑上傳的檔案,路徑都變成了這種格式 “C:\fakepath\檔名”。
這裡寫圖片描述

以前做圖片上傳時沒留意過這個fakepath,直譯過來是偽路徑,網上搜了一下 說是瀏覽器為了保護使用者的檔案安全,隱藏了上傳的真實路徑,用fakepath代替,或者調整瀏覽器的相關安全設定可以解決這個問題。

從剪下板獲取圖片資訊

首先要明確兩點:

  • 剪下板裡可以裝1個或者多個數據項
  • 貼上剪下板裡的截圖 跟 貼上一個圖片檔案 不一樣。例如:右鍵複製一個圖片得到的是一個圖片檔案

我們這裡討論的是前者——剪下板裡的截圖,暫不考慮後者。從剪下板貼上圖片的教程很多,這裡總結一下,大致分為4步:

  1. 攔截元素的paste事件
  2. 找到event資料中的我們需要的圖片資訊

    e.clipboardData.items[0].type.indexOf('image') > -1
  3. 拿到圖片的dataURL

    var reader = new FileReader(),
        file = e.clipboardData.items[0].getAsFile();
    reader.onload = function(e){
        //this.result 可以得到圖片的base64
    }
    reader.readAsDataURL(file);

    readAsDataURL : The readAsDataURL method is used to read the contents of the specified Blob or File. When the read operation is finished, the readyState becomes DONE, and the loadend is triggered. At that time, the result attribute contains the data as a URL representing the file’s data as a base64 encoded string.

    readAsDataURL 方法用來讀Blob或File內容,當讀操作完成之後,readyState 狀態變成DONE,並觸發 loadend 方法。此時,result 屬性就包含了一個URL字串,即檔案資料的base64編碼格式。

  4.  var formData = new FormData();
     formData.append('file', file , filename); //第三個是檔名

注意:在Chrome中能夠直接通過clipboardData獲取截圖的圖片資料,在火狐等瀏覽器中無法直接獲取圖片資料,所以可以在貼上的時候hack一下,ff裡編輯[contenteditable]時,貼上一個圖片,ff會把圖片當作圖文混排的插圖將它轉化為一個<img/>元素插進去,img的src屬性就是base64的dataURL

base64轉Blob

function base64ToBlob(base64Str){
    var dataURI = base64Str;
    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 (i = 0; i < byteString.length; i += 1) {
         intArray[i] = byteString.charCodeAt(i);
    }

    return intArray//new Blob([intArray], { type:  mimeString}); //轉成blob
}