フォームのテスト中に、 JavaScript のバリデーションチェックのために以下のような絵文字を入力してみました。
test@example.com👼
![入力した文字列、「test@example.com👼」](https://labor.ewigleere.net/wp-content/uploads/2020/09/chrome_input_type_email_punycode-20200928_1.png)
ASCII文字以外は正規表現的にエラーになることを予想していました。
ところが、 Chrome ではエラーにならずにチェックを通ってしまいました。
何事かと思ってバリデーション中の値を出力してみると、以下のようになっていました。
test@example.xn--com-h713b
![試しに代入されたはずの値を出力すると、「test@example.com👼」のはずが、「test@example.xn--com-h713b」という文字列に勝手に変換されている](https://labor.ewigleere.net/wp-content/uploads/2020/09/chrome_input_type_email_punycode-20200928_2.png)
……あれ、天使がいなくなっている。そして変換された結果が「アルファベット、数字、ハイフン」のいずれかなので今回想定していた正規表現では通ってしまいます。
![Firefox では「test@example.com👼」のまま表示された](https://labor.ewigleere.net/wp-content/uploads/2020/09/chrome_input_type_email_punycode-20200928_3.png)
Chrome で検証が発生したため、 Firefox でも確認。 Firefox では入力された値がそのまま表示されました。
検索してみたところ、 Chrome は Unicode で書かれたドメインの文字列を Punycode (DNS で使用可能なアルファベット、数字、ハイフンのみの文字列に変換する文字列符号化方式) として扱うようです。
※同じエンジンを積んでいるためか Vivaldi も同じ挙動でした。
確かに日本語ドメインとか扱うとき困りますからね…… Chrome の仕様ということで、原因が分かったので納得しました。
国際化ドメイン名(IDN / Internationalized Domain Name) を取り扱うための仕組みで、 RFC 3492 で規定されているのならばむしろ通さない方がアレなのでそのままにするということで今回のケースは終了しました。
参考
- Punycode(ピュニコード)変換って知ってますか? | レコチョクのエンジニアブログ
- JPRS用語辞典|Punycode(ピュニコード)
- RFC 3492 – Punycode: A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA)