簡體   English   中英

React-Native(或JS)解碼Base64為ZIP文件

[英]React-Native (or JS) Decode Base64 to ZIP File

我正在開發一個[試圖]優化在 AWS 中存儲圖像和視頻的應用程序,同時還考慮數據的檢索。

我分 2 個步驟執行此操作: A. 將數據存儲到 AWS & B. 從 AWS 檢索數據 我正在嘗試解決的當前問題存在於B: Step 3中。 我無法將 Base64 正確解碼為 Zip 文件。

答:我將數據存儲在一個 6 步過程中,以確保數據盡可能地被壓縮(節省成本)和加密,以便只有用戶才能訪問它(加密)。

  1. 從用戶獲取圖像/視頻
    原因:用戶數據選擇
import { launchImageLibrary } from 'react-native-image-picker';
launchImageLibrary(options, (response) => {
    if(response.assets) {
        const assets = response.assets;
        completeCallback(assets);
    }
    else if(response.errorCode) {
        const message = response.errorMessage;
        console.log(message);
    }
    else {
        cancelCallback();
    }
});
  1. 將圖像從原始位置存儲到文檔目錄中
    原因:綜合定位到Zip
static async copyFilesToDocumentDirectory(urls) {
    var path = `${RNFS.DocumentDirectoryPath}/media`;
    let existDir = await RNFS.exists(RNFS.DocumentDirectoryPath + '/media').then(boolean => boolean);
    if(!existDir) { RNFS.mkdir(path); };
    return Promise.all(urls.map(url => {
        return RNFS.exists(url)
            .then((status) => {
                if(status) {
                    var filename = url.substring(url.lastIndexOf('/')+1);
                    var newPath = path + "/" + filename;
                    return RNFS.copyFile(url, newPath);
                };
            });
    }));
};
  1. Zip 上傳文件
    原因:應該減小文件大小,但不一定適用於所有情況
static zipDocumentDirectory = async () => {
    var sourcePath = `${RNFS.DocumentDirectoryPath}/media`;
    var targetPath = `${RNFS.DocumentDirectoryPath}/myFile.zip`;
        
    return await zip(sourcePath, targetPath);
}
  1. 將 Zip 編碼為 base64
    編碼數據以便我可以加密它
AWS.getPresignedURLPut(DBKey, passCode, 
    async (url) => {
        await RNFS.readFile(zipURI, 'base64')
        .then(res => {
                // Next Section
                ...
        }, (err) => {
            console.log(`Err: ${err}`)
        }
    );
  1. 加密base64
    原因:端到端加密
const encryptedData = CryptoJS.AES.encrypt(res, ENKey).toString();
const json =
{
    'DBKey': DBKey,
    'PassCode': passCode,
    'base64data': encryptedData
};
// Store data in Next Section
  1. 存儲在數據庫中
    原因:數據庫存儲
AWS.storeJSONToAWSS3PresignedURL(json, url, onComplete);

B.我以相同的方式檢索數據,只是順序相反。

  1. 從數據庫中檢索加密的 Base64
    原因:獲取原始數據
AWS.getJSONFromAWSS3PresignedURL(url); //returns Base64 String
  1. 解密為原始 Base64
    原因:需要獲取原始Base64
/* Decryption */
const bytes = CryptoJS.AES.decrypt(data, endToEndEncryptionKey)
originalBase64 = bytes.toString(CryptoJS.enc.Utf8);
  1. 將 Base64 解碼為 Zip 文件問題
    原因:需要包含視頻/照片的原始 Zip 文件
static writeBase64ToDocumentDirectory = async (base64) => {
    var path = `${RNFS.DocumentDirectoryPath}/myFile.zip`;
    const blob = b64toBlob(base64);
    const file = new File([blob], path, { type: 'application/x-zip-compressed' });
    console.log(`F:`);
    console.log(file);
    console.log(`B:`);
    console.log(blob);
};

const b64toBlob = (b64Data, contentType='', sliceSize=512) => {
    const byteCharacters = global.atob(b64Data);
    const byteArrays = [];
  
    for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
      const slice = byteCharacters.slice(offset, offset + sliceSize);
  
      const byteNumbers = new Array(slice.length);
      for (let i = 0; i < slice.length; i++) {
        byteNumbers[i] = slice.charCodeAt(i);
      }
  
      const byteArray = new Uint8Array(byteNumbers);
      byteArrays.push(byteArray);
    }
  
    const blob = new Blob(byteArrays, {type: contentType});
    return blob;
}

/*
F:
{"_data": {"__collector": {}, "blobId": "9341bc78-11e7-428c-96c4-e761dc47f75a", "lastModified": undefined, "name": "/var/mobile/Containers/Data/Application/986B087C-A19A-4DDA-9180-831B4EDE89B9/Documents/myFile.zip", "offset": 0, "size": 1948698, "type": "application/x-zip-compressed"}}

B:
{"_data": {"__collector": {}, "blobId": "66b4e283-5a26-4684-a6f7-49f3615c8509", "lastModified": undefined, "offset": 0, "size": 1948698, "type": ""}}
*/
  1. 最后一步是解壓縮文件,但它不存在。
await RNFS.readDir(`${RNFS.DocumentDirectoryPath}`)
.then((result) => {
    console.log(`Zip Path: ${result} -- ${result.length}`);
    console.log(result);
});

/*
Zip Path:  -- 0
[]
*/

問題:我似乎找不到將 base64 轉換為解碼的 zip 文件的方法。

工作驗證:我知道這可以工作,因為我可以使用這個網站解碼 base64。 但是,我無法重現代碼以在設備本地執行相同的操作。

const b64toBlob = (b64Data, contentType='', sliceSize=512) => {
    const byteCharacters = global.atob(b64Data);
    const byteArrays = [];
  
    for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
      const slice = byteCharacters.slice(offset, offset + sliceSize);
  
      const byteNumbers = new Array(slice.length);
      for (let i = 0; i < slice.length; i++) {
        byteNumbers[i] = slice.charCodeAt(i);
      }
  
      const byteArray = new Uint8Array(byteNumbers);
      byteArrays.push(byteArray);
    }
  
    const blob = new Blob(byteArrays, {type: contentType});
    return blob;
};

將 Base64 字符串轉換為 Blob 后,您可以使用 File 構造函數和 react-native-fs 庫中的 writeFile 方法將 Blob 寫入文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM