Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
4
Help us understand the problem. What is going on with this article?
@kerupani129

Fetch API で Shift_JIS の HTML をDOM として読み込む

fetch で Shift_JIS を扱おうとしたら文字化けしたので、解決方法を書きます。

1. 流れ

  1. fetch で DOM として直接読み込むことはできない
  2. なので、一回 text として読み込んで DOM に parse する
  3. ところが、response.text() で文字コードが UTF-8 以外で文字化けし、解決方法は (おそらく) ない (Content-Typecharset を指定しても効果なし)
  4. なので、一度バイナリデータとして読み込み、文字コードを指定して文字列に変換し、そこから DOM に parse する

参考「JavaScriptのFetch APIで返ってきたものをDOMとして扱う - ひと夏の技術
参考「fetch APIでUTF8以外のエンコーディングだと辛い – 阿Qさんと一緒

2. ソースコード

2.1. 方法 1: Response -> Blob -> fileReader.readAsText()

(async () => {

    // 
    const readAsText = (blob, encoding = null) => new Promise(resolve => {
        const reader = new FileReader();
        reader.onload = () => { resolve(reader.result) };
        reader.readAsText(blob, encoding);
    });

    const parseHTML = html => new DOMParser().parseFromString(html, 'text/html');

    // 
    const url = '...';

    const response = await fetch(url);
    const blob = await response.blob();
    const html = await readAsText(blob, 'shift-jis');
    const dom = parseHTML(html);

    // 処理
    console.log(dom.head);

})();

2.2. 方法 2: Response -> ArrayBuffer -> textDecoder.decode()

TextDecoder が使用できるブラウザならこちらの方がシンプルに書けます。

※新 Edge は対応していないようです。

参考「TextDecoder - Web API | MDN

(async () => {

    // 
    const decodeAsText = (arrayBuffer, encoding = null) => new TextDecoder(encoding).decode(arrayBuffer);

    const parseHTML = html => new DOMParser().parseFromString(html, 'text/html');

    // 
    const url = '...';

    const response = await fetch(url);
    const arrayBuffer = await response.arrayBuffer();
    const html = decodeAsText(arrayBuffer, 'shift-jis');
    const dom = parseHTML(html);

    // 処理
    console.log(dom.head);

})();
4
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
4
Help us understand the problem. What is going on with this article?