Estava analisando uma requisição POST
em um site e, no formData
da requisição, me deparei com um “unable to decode value” em uma das chave-valor. O valor sem decodificação acabou gerando um problema na aplicação que ajudo a desenvolver: não era possível serializar a informação para JSON e esse erro estourava no console do browser.
Acontece que o Chrome não estava decodificando um ArrayBuffer. O ArrayBuffer é um objeto built-in do JavaScript usado para representar algum dado binário com tamanho fixo. O construtor ArrayBuffer()
cria um novo ArrayBuffer
com um tamanho de bytes fornecido como argumento.
Como não dá para manipular o conteúdo do ArrayBuffer diretamente, podemos criar um TypedArray, um tipo de array para visualizar esses buffers binários e para representá-los num formato específico.
Por exemplo:
const buffer = new ArrayBuffer(8);
const view = new Int32Array(buffer);
O código acima cria um buffer de 8 bytes e depois cria uma view usando o construtor Int32Array
, que é um typed array de inteiros com sinal de 32 bits. Só para deixar claro, 8 bytes equivalem a 64 bits.
Como transformar uma string em ArrayBuffer
Podemos, por exemplo, transformar um array de strings em um array com vários ArrayBuffer utilizando o TextEncoder
. O TextEncoder basicamente pega a informação e emite uma stream de bytes em UTF-8:
const encoder = new TextEncoder();
const stringsArr = ["xpto", "mock", "10"]
const stringsEncoded = stringsArr.map(string => encoder.encode(string));
const stringsBuffers = stringsEncoded.map(uint8 => uint8.buffer);
O que fizemos acima:
- Instanciamos um
TextEncoder
chamado “encoder” - Criamos um array de strings
- Mapeamos o array e chamamos o método
encode
do nosso encoder para cada string - Com as strings encodadas em
Uint8Array
, chamamos a propriedadebuffer
de cada uma delas, retornando o ArrayBuffer referenciado pelo typed array
Teste um console.log(stringsBuffers)
no console do seu browser e veja os array buffers no array.
Por que o TextEncoder transforma em Uint8Array?
Os browsers mais comuns não tem mais suporte a outros encodings que não sejam UTF-8. Você pode ler mais sobre isso nessa pergunta do StackOverflow.
Como transformar um ArrayBuffer em uma string
Usando a constante do exemplo anterior:
const decoder = new TextDecoder();
const stringsDecoded = stringsBuffers.map(buffer => decoder.decode(buffer));
O que fizemos acima:
- Instanciamos um
TextDecoder
, que consegue decodificar UTF-8, ISO-8859-2, KOI8-R, GBK, entre outros - Mapeamos nosso array de array buffers e utilizamos o método
decode
do nosso decoder para cada um
Dê um console.log
e veja o resultado.
Fontes:
MDN ArrayBuffer
MDN TypedArray
TextEncoder
TextDecoder
StackOverflow
Esse texto não tem intenção de esgotar o tema. Acrescente nos comentários, e também aponte erros quando os identificar.
Top comments (1)
Você tem alguma ideia de como manipular o ArrayBuffer que é gerado quando fazemos uma requisição POST e nela temos um FormData contendo campos e arquivos?
dev-to-uploads.s3.amazonaws.com/up...