您好,祝您 2021 年更快樂、更健康!
我正在基于 Websockets 協議在 JS 客戶端和 AS3 服務器之間建立一個小型通信介面。由于各種原因,我需要對有效負載進行壓縮和 base64 編碼。從 AS3 到 JS 一切都是這樣作業的(使用https://github.com/blooddy/blooddy_crypto來處理 Base64 en/decryption):
function encodeMessage(message:String):String{
var rawData:ByteArray=new ByteArray()
rawData.writeUTFBytes( encodeURIComponent(message) );
rawData.compress();
var b64 = Base64.encode(rawData);
return b64;
};
用 pako 在 JS 中解碼以進行通貨膨脹(https://github.com/nodeca/pako):
decodePayload(payload){
let rawfile = (atob(payload));
var bytes = [];
for (var fileidx = 0; fileidx < rawfile.length; fileidx ) {
var abyte = rawfile.charCodeAt(fileidx) & 0xff;
bytes.push(abyte);
}
var plain = pako.inflate(bytes);
var enc = "";
for (var i = 0; i < plain.length; i ) {
enc = String.fromCharCode(plain[i]);
}
return decodeURIComponent(enc);
}
現在另一個方向產生了一些問題:在 JS 我使用:
encodeMessage(message){
let enc = encodeURIComponent(message)
let zlib = pako.deflate(enc)
let b64 = btoa(zlib);
return b64;
}
但后來我遇到了 AS3 方面的問題:
function decodePayload(payload:String){
var ba:ByteArray = Base64.decode(payload);
//this is where the error happens
ba.uncompress();
}
錯誤是“錯誤:錯誤 #2058:解壓縮資料時出錯。” 我懷疑我從 pako.deflate 收到的位元組與 AS3 使用的不同?
歡迎任何指點!
uj5u.com熱心網友回復:
這是解決方案 - 當然是一個愚蠢的小疏忽;)
在 JS 的編碼函式中,Uint8Array 需要先轉換為 BinaryString,然后才能進行 Base64 編碼:
function encodeMessage(message){
let enc = encodeURIComponent(message);
let zlib = pako.deflate(enc);
let binstring = convertUint8ArrayToBinaryString(zlib);
let b64 = btoa(binstring);
return b64;
};
function convertUint8ArrayToBinaryString(u8Array) {
var i, len = u8Array.length, b_str = "";
for (i=0; i<len; i ) {
b_str = String.fromCharCode(u8Array[i]);
}
return b_str;
}
那么羅斯威爾一切都很好。
uj5u.com熱心網友回復:
如果您的 AS3 代碼僅用于 SWF 檔案或您有一個 AIR 專案,這并不明顯。
- 如果制作 AIR 專案:
嘗試使用uncompress.apply...(代碼尚未測驗)。
//# this is where the error happens
//ba.uncompress();
//# try this..
ba.uncompress.apply(ba, ["deflate"]);
- 如果制作 SWF 專案:
當我需要在瀏覽器上運行的 SWF 中使用 Deflate 演算法時,我使用了 Zlib 的埠。
獲取as3zlib:https ://github.com/BenV/as3zlib (是 Zlib for Java 的一個埠)。
注意:雖然在 JS 中創建本地變數而不是全域變數更好,但這是 JavaScript 的一個怪癖,實際上在大多數類似 C 的語言(Java、C#、AS3 等)中這是相反的,全域變數比不斷創建變數更便宜每次呼叫函式時的本地變數。
這是一個使用示例:
//# import Zlib Class
import Zlib;
//# setup global vars
var zlibdecomp :Zlib;
var ba :ByteArray = new ByteArray;
var decoded_BA :ByteArray = new ByteArray;
//# try Deflate algo...
function decodePayload(payload:String)
{
zlibdecomp = new Zlib;
ba.clear(); //in case it already has data from a prev decode
//# all code below can be done in this one line
//ba = zlibdecomp.uncompress( Base64.decode(payload) );
ba = Base64.decode(payload);
//# this is where the error happens...
//ba.uncompress();
//# try this...
decoded_BA = zlibdecomp.uncompress( ba ); //inflate to original big from small/compressed
//ba = decoded_BA; //if this way of updating is needed
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/417767.html
標籤:
