5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

zlibでGZIP形式で圧縮された文字列のレスポンスデータをJavaScriptで解凍する

Last updated at Posted at 2023-06-21

Lambdaで構築されたAPIで返却値が大きいせいでペイロードのデータサイズ制限(6MB以上は制限に引っかかる)に引っかかってしまうとのことで、Lambda側でgzip圧縮されたデータをフロントで解凍する必要が出てきたときに、1~2日くらいハマったので備忘録。

Lambdaのペイロード制限について

API側は言語はPythonでzlibライブラリを使っていたので、フロント側も同じくzlib.jsを使うことに。

いざ、実装!!

以下の記事を参考に実装してみる。

実装中にハマった部分

①Pythonでbase64エンコードされた文字列をJavaScriptでbase64デコードすることがまずできず、はまる。。。

②デコードできるようになったが、、、zlib.jsでungzipできない。。。

Pythonでbase64エンコードされた文字列をJavaScriptでbase64デコードする

1日くらい検索したがなかなか見つけられず、、、ようやく見つけたのが以下、

NG

baseString = 'hogehoge'
encodedString = baseString.encode()
base64encodedString = base64.b64decode(encodedString)
responseString = base64encodedString.decode()

return responseString

//responseから取得したbase64エンコードされた文字列
const base64encodedString = "SGVsbG8sIHdvcmxkIQ=="; 
const base64decodedString = atob(base64encodedString)

記事によると、Pythonでエンコード時に ascii 指定をしてからbase64エンコードしないととJavaScriptでは正しくデコードできないとのこと。

JavaScriptはそのままで、Python側を変更

OK

baseString = 'hogehoge'
encodedString = baseString.encode('ascii')
base64encodedString = base64.b64decode(encodedString)
responseString = base64encodedString.decode('ascii')

return responseString

zlib.jsでungzipできないのでpako.jsでungzipする

なんで同じzlibなのに、、、試行錯誤の末、ライブラリを pako 変えてみた。
もともと、SessionStorageを格納する際にデータ圧縮するライブラリとしてつかっていたものでGzip解凍ができるとのことでやってみたらうまくいった。

zlibベースの高速なデータ圧縮・解凍ライブラリとのことでライセンスはMITです。

実装

import zlib

baseString = 'hogehoge'
encodedString = baseString.encode('ascii')
compressedData = zlib.compress(encodedString)
base64encodedString = base64.b64decode(compressedData)
responseString = base64encodedString.decode('ascii')

return responseString

const unescapeUnicode = (str: string) => {
  return str.replace(/\\u([a-fA-F0-9]{4})/g, function(x, y) {
    return String.fromCharCode(parseInt(y, 16))
  })
}

const handleUnGzipData = (responseCompressed: string) => {
  try {

   // base64エンコードされたgzipの文字列をbase64デコード
    const gzipedData = atob(responseCompressed)

   // 解凍するには文字列をバイナリにする必要があるのでバイナリ変換
    const gzipedDataArray = Uint8Array.from(gzipedData, c => c.charCodeAt(0))

    // gzip解凍
    const ungzipedData = pako.ungzip(gzipedDataArray, { to: 'string' })

  // Unicodeエスケープシーケンスで日本語に戻す
    const output = unescapeUnicode(ungzipedData)

  // 文字列をオブジェクト変換
    const responseObject = JSON.parse(output)

    return responseObject
  } catch (error) {
    return ''
  }
}

勉強になりました。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?