saiko memo

じぶん用の技術メモ

非同期で取得したデータがIE11で文字化けする場合の対処法

axiosでデータを取得後にDOM操作を行おうとしたところ、IE11のみ文字化けする事例があったのでメモ。

発生状況

以下のようにresponseType: 'document'を指定して取得したところ、IE11のみ文字化けが発生。

axios.get( '取得したいデータのURL', { responseType: 'document' } )
  .then( res => res.data )
  .then( data => {
    console.log( data ); // IEで文字化けする
  } );

取得したいデータの文字コードUTF-8でない可能性もあったのですが、根本の原因はわからず…。

ただresponseType: 'document'を指定しない場合文字化けは発生しないので、いったん無指定で取得した後にDocumentオブジェクトに変換すればよさそう。

何か方法はないかなーと検索したところ、DOMParserというAPIがありました。

DOMParser - Web API | MDN

DOMParser インターフェイスは、 XML や HTML ソースコードを文字列から DOM の Document に解釈する機能を提供します。

上記のコードを以下のように修正。するとIE11でも文字化けなく取得することができました。

axios.get( '取得したいデータのURL' )
  .then( res => res.data )
  .then( data => {
    const domParser = new DOMParser();
    const doc = domParser.parseFromString( data, 'text/html' );
    console.log( doc );
  }

dl要素内のdivの使い方についてメモ

HTML5.2よりdl要素内でdiv要素が使用できるようになったのですが、誤解していた部分があったのでメモ。

単純に「dl要素の子孫要素としてdivが使える」と覚えておりdiv要素をdd要素のラッパーとして使おうとしていたのですが、HTML Living Standardに反する使い方だったようです1

<!-- これはNG -->
<dl>
  <dt></dt>
  <div>
    <dd></dd>
    <dd></dd>
    <dd></dd>
  </div>
</dl>

dd要素の前に配置される兄弟要素はdtまたはdd要素と決まっており、この点が仕様違反となっていました。

つまり、dl要素内でdivを使う際には、dtおよびdd要素をまとめてラップする形で使用するのが仕様に沿った使い方となります。

<!-- これはOK -->
<dl>
  <div>
    <dt></dt>
    <dd></dd>
    <dd></dd>
    <dd></dd>
  </div>
</dl>

ただ上記の形では、dd要素群をひとまとまりに扱いたい場合に少し不都合があります。そのため今回は仕様に合った形で下記のように書き換えました。

<!-- 仕様に合う形に書き換え -->
<dl>
  <dt></dt>
  <dd>
    <ul>
      <li></li>
      <li></li>
      <li></li>
    </ul>
  </dd>
</dl>

ネストが増えているのが少し気持ち悪いですが、そこは仕方ないということで。

参考


  1. 2021.2.10現在

配列に変換し、かつmapで処理する

Array.from()Array.prototype.map()の組み合わせでもできますが、実はArray.from()だけでできます。

Array.from( '12345', i => i * 2 ); // [ 2, 4, 6, 8, 10 ]

Array.from()の第2引数にはmap関数を書くことができるため、わざわざ別に関数を書かなくてもArray.from()のみでmap処理まで完結させることができます。

[参考]