1. 程式人生 > >上傳base64圖片到七牛雲端儲存

上傳base64圖片到七牛雲端儲存

簡單的說一下需求:將canvas繪畫生成的圖片上傳至七牛。

用canvas生成的圖片是base64編碼,上傳base64編碼圖片到七牛雲公開的介面如下:

POST /putb64/<Fsize>/key/<EncodedKey>/mimeType/<EncodedMimeType>/crc32/<Crc32>/x:user-var/<EncodedUserVarVal>
Host: upload.qiniu.com
Authorization: UpToken <UpToken>
Content-Type: application/octet-stream

<Base64EncodedFileContent
>

引數說明:

引數名稱 必填 說明
/<Fsize> 檔案大小。支援傳入 -1 表示檔案大小以 http request body 為準。
/<EncodedKey> 如果沒有指定則:如果 uptoken.SaveKey 存在則基於 SaveKey 生產 key,否則用 hash 值作 key。EncodedKey 需要經過 base64 編碼。具體可以參照:URL 安全的 Base64 編碼。
/<EncodedMimeType> 檔案的 MIME 型別,預設是 application/octet-stream。
/<Crc32> 檔案內容的 crc32 校驗值,不指定則不進行校驗。
Host 上傳域名 up.qiniu.com 用於服務端上傳,upload.qiniu.com 用於客戶端的上傳。

注意事項:

在這裡補充一下:

補充點
1、base64編碼 base64 的格式為 “data:image/png;base64,****==”,逗號之前都是一些說明性的文字,我們只需要****部分
2、Base64圖片編碼原理 Base64編碼要求把3個8位位元組(3*8=24)轉化為4個6位的位元組(4*6=24),之後在6位的前面補兩個0,形成8位一個位元組的形式。 如果剩下的字元不足3個位元組,則用0填充,輸出字元使用’=’,因此編碼後輸出的文字末尾可能會出現1或2個’=’
3、當我們知道base64編碼的圖片的字元大小,怎麼計算圖片的檔案流大小呢? 通過base64編碼原理我們知道,base64的圖片字元流中的每8個字元就有兩個是用0補充,而且字元流的末尾還可能存在‘=’號,我們可以通過這個原理計算圖片的檔案流大小。

    
在這裡遇到一個坑,
通過裁剪陣列的方式獲得/<Fsize>
如下程式碼:

 var arr = base64.split(",");
 var str = arr[1].split("==");
 var n = str[0].length;
 var Fsize=parseInt(n-(n/8)*2);

報錯 {error: "illegal base64 data at input byte 4"}

獲取檔案大小的時候,切記要通過檔案流的方式獲取。而不是通過圖片標籤然後轉換後獲取

//把頭部的data:image/png;base64,(注意有逗號)去掉
var arr = base64.split(','), 
mime = arr[0].match(/:(.*?);/)[1],
len = mime.length;
var subLen = parseInt(len + 13);
base64=base64.substring(subLen);
//通過base64編碼字元流計算檔案流大小函式
function fileSize(str) {
    var fileSize;
    //找到等號,把等號也去掉
    if (str.indexOf('=') > 0) {
       var indexOf = str.indexOf('=');
       str = str.substring(0, indexOf);//把末尾的’=‘號去掉
     }
    fileSize = parseInt(str.length - (str.length / 8) * 2);
    return fileSize;
}

2、xhr.setRequestHeader(“Authorization”, “UpToken 填寫你從服務端獲取的上傳token”); 這裡的UpToken與後面的字串保留一個空格。後面跟上你在服務端請求的token的字串。具體你通過什麼樣子的請求方式獲得是客戶自己要關心的事情。
    
    
----------------------------
    
    
好了,附上跑通的程式碼,希望能幫到你,當然,如果你有更好的方式實現,歡迎留言,學習學習

function putb64(base64) {
    var pic = base64.replace(/^.*?,/, '');
    $.ajax({
        type: 'post',
        url: "https://test.dankal.cn/wansj/public/index.php/api/Index/upToken",
        success: function (data) {
            var token = data.uptoken;
            // 把字串轉換成json
            function strToJson(str) {
                var json = eval('(' + str + ')');
                return json;
            }
            var url = "http://up-z0.qiniu.com/putb64/-1/";
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                    var keyText = xhr.responseText;
                    // 返回的key是字串,需要裝換成json
                    keyText = strToJson(keyText);
                    //keyText.key 是返回的圖片檔名
                    var key = keyText.key;
                    var getToken = $('.token').val();
                    $.ajax({
                        type: 'post',
                        url: "http://test.dankal.cn/wansj/public/index.php/api/Index/getShareUrl",
                        data:{
                            token:getToken,
                            file_key:key,
                        },
                        success: function (data) {
                            var shareUrl = data.share_url;
                            console.log(shareUrl);
                        },
                        error: function () {
                            console.log("上傳base64至七牛失敗");
                        }
                    })
                }
            }
            xhr.open("POST", url, true);
            xhr.setRequestHeader("Content-Type", "application/octet-stream");
            xhr.setRequestHeader("Authorization", "UpToken " + token);
            xhr.send(pic);
        },
        error: function () {
            console.log("sendFile請求出錯");
            $('.loading').html("親,真抱歉,圖片上傳失敗");
        }
    })
}