18
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Fetch API や Blob で UTF-8 以外の文字コードを扱う

Last updated at Posted at 2018-09-18

1. 予備知識

fetch で得た ResponseBlob のメソッドはテキストデータの文字コードを常に UTF-8 として扱うため、Shift_JIS 等の UTF-8 以外の文字コードでは文字化けします。

参考「Response.text() - Web API | MDN
参考「Blob.text() - Web API | MDN

直接 UTF-8 以外の文字コードを扱うことはできないため、バイナリデータを経由して文字コードを指定してテキストデータに変換します:

  • 方法 1: ArrayBuffer を経由して TextDecoder を用いる
    • textDecoder.decode(arrayBuffer)
  • 方法 2: Blob を経由して FileReader を用いる
    • fileReader.readAsText(blob)
    • 古いやり方のため、本記事では不説明

参考「TextDecoder: decode() メソッド - Web API | MDN
参考「FileReader.readAsText() - Web API | MDN

2. テキストの場合

const textDecoder = new TextDecoder('shift-jis');

// 
const responseA = await fetch('data.txt')
const arrayBufferA = await responseA.arrayBuffer();
const textA = textDecoder.decode(arrayBufferA);

console.log(textA);

// 
const responseB = await fetch('data.txt');
const blob = await responseB.blob();
const arrayBufferB = await blob.arrayBuffer();
const textB = textDecoder.decode(arrayBufferB);

console.log(textB);

3. JSON の場合

文字コードを指定する場合は response.json() を使えないため、通常のテキストに変換してから JSON.parse() を用います。

const textDecoder = new TextDecoder('shift-jis');

// 
const responseA = await fetch('data.json')
const arrayBufferA = await responseA.arrayBuffer();
const textA = textDecoder.decode(arrayBufferA);
const valueA = JSON.parse(textA);

console.log(valueA);

// 
const responseB = await fetch('data.json');
const blob = await responseB.blob();
const arrayBufferB = await blob.arrayBuffer();
const textB = textDecoder.decode(arrayBufferB);
const valueB = JSON.parse(textB);

console.log(valueB);

参考「Response.json() - Web API | MDN
参考「JSON.parse() - JavaScript | MDN

4. XML および HTML の場合

DOMParser を併用することで、XML および HTML のテキストデータを DOM として扱うことができます。

XML
const textDecoder = new TextDecoder('shift-jis');

const domParser = new DOMParser();

// 
const responseA = await fetch('data.xml')
const arrayBufferA = await responseA.arrayBuffer();
const textA = textDecoder.decode(arrayBufferA);
const documentA = domParser.parseFromString(textA, 'application/xml');

console.log(documentA);

// 
const responseB = await fetch('data.xml');
const blob = await responseB.blob();
const arrayBufferB = await blob.arrayBuffer();
const textB = textDecoder.decode(arrayBufferB);
const documentB = domParser.parseFromString(textB, 'application/xml');

console.log(documentB);
HTML
const textDecoder = new TextDecoder('shift-jis');

const domParser = new DOMParser();

// 
const responseA = await fetch('data.html')
const arrayBufferA = await responseA.arrayBuffer();
const textA = textDecoder.decode(arrayBufferA);
const documentA = domParser.parseFromString(textA, 'text/html');

console.log(documentA);

// 
const responseB = await fetch('data.html');
const blob = await responseB.blob();
const arrayBufferB = await blob.arrayBuffer();
const textB = textDecoder.decode(arrayBufferB);
const documentB = domParser.parseFromString(textB, 'text/html');

console.log(documentB);

参考「DOMParser - Web API | MDN

5. おまけ: Response からメソッドで変換可能なデータ形式について

Response からメソッドで変換可能なデータ形式は以下の通りです:

  • バイナリデータ
    • ArrayBuffer
    • Blob
    • FormData
  • テキストデータ
    • テキスト
    • JSON

参考「メソッド - Response - Web API | MDN

18
8
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
18
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?