Javascript (Node.js)で文字列エスケープ

目的

  • Node.js で実装をしていて、改行文字がエスケープされていたが、どうやって戻せば良いか分からなかったので調べてまとめる

Javascript の文字列のエスケープ

Javascript では文字列の加工が 2 種類ある気がする

  • エスケープ:改行などの特殊文字を見える形に加工する(\n => \n)
  • 無害化(サニタイジング):HTML や JSON オブジェクトを解釈・実行させずに渡せるよう加工する

Javascript でエスケープ、サニタイズに使われる関数

  • encodeURIComponent
    • 変換対象が少ない encodeURI もある
  • JSON.stringify
    • JSON とついているが、オブジェクト型じゃなくても使える
    • 改行文字のバックスラッシュエスケープが行われる
  • escape
    • 非推奨
  • toString(‘Base64’)

検証

エンコードする対象の文字列は以下の 4 つ

  • JSON で解釈される記号

” \ / \b \f \n \r \t

  • URL で使わないほうが良い記号

: ? # / ? @ % ! ( ) [ ] & ’ * + , ; =

  • HTML 解釈される記号

< > & © ® ™ ” ’ ¥

  • 英語以外の文字

abc123 あいう ЁЂЃ

結果

そのまま出力

const str1 = `"\/\b\f\n\r\t`;
const str2 = `:?#/?@%!()[]&'*+,;=`;
const str3 = `<> &©® ™"'¥`;
const str4 = `abc123あいうЁЂЃ`;

console.log(str1);
console.log(str2);
console.log(str3);
console.log(str4);

出力結果

"/


:?#/?@%!()[]&'*+,;=
<> &©® ™"'¥
abc123あいうЁЂЃ

encodeURIComponent

const str1 = `"\/\b\f\n\r\t`;
const str2 = `:?#/?@%!()[]&'*+,;=`;
const str3 = `<> &©® ™"'¥`;
const str4 = `abc123あいうЁЂЃ`;

console.log(encodeURIComponent(str1));
console.log(encodeURIComponent(str2));
console.log(encodeURIComponent(str3));
console.log(encodeURIComponent(str4));

出力結果

%22%2F%08%0C%0A%0D%09
%3A%3F%23%2F%3F%40%25!()%5B%5D%26'*%2B%2C%3B%3D
%3C%3E%20%26%C2%A9%C2%AE%20%E2%84%A2%22'%C2%A5
abc123%E3%81%82%E3%81%84%E3%81%86%D0%81%D0%82%D0%83

escape

const str1 = `"\/\b\f\n\r\t`;
const str2 = `:?#/?@%!()[]&'*+,;=`;
const str3 = `<> &©® ™"'¥`;
const str4 = `abc123あいうЁЂЃ`;

console.log(escape(str1));
console.log(escape(str2));
console.log(escape(str3));
console.log(escape(str4));

出力結果

%22/%08%0C%0A%0D%09
%3A%3F%23/%3F@%25%21%28%29%5B%5D%26%27*+%2C%3B%3D
%3C%3E%20%26%A9%AE%20%u2122%22%27%A5
abc123%u3042%u3044%u3046%u0401%u0402%u0403

JSON.stringify

const str1 = `"\/\b\f\n\r\t`;
const str2 = `:?#/?@%!()[]&'*+,;=`;
const str3 = `<> &©® ™"'¥`;
const str4 = `abc123あいうЁЂЃ`;

console.log(JSON.stringify(str1));
console.log(JSON.stringify(str2));
console.log(JSON.stringify(str3));
console.log(JSON.stringify(str4));

出力結果

"\"/\b\f\n\r\t"
":?#/?@%!()[]&'*+,;="
"<> &©® ™\"'¥"
"abc123あいうЁЂЃ"

Base64

const str1 = `"\/\b\f\n\r\t`;
const str2 = `:?#/?@%!()[]&'*+,;=`;
const str3 = `<> &©® ™"'¥`;
const str4 = `abc123あいうЁЂЃ`;

console.log(Buffer.from(str1).toString('base64'));
console.log(Buffer.from(str2).toString('base64'));
console.log(Buffer.from(str3).toString('base64'));
console.log(Buffer.from(str4).toString('base64'));

出力結果

Ii8IDAoNCQ==
Oj8jLz9AJSEoKVtdJicqKyw7PQ==
PD4gJsKpwq4g4oSiIifCpQ==
YWJjMTIz44GC44GE44GG0IHQgtCD

デコード

それぞれの関数に対応するデコード関数は以下

エンコード関数デコード関数
encodeURIComponentdecodeURIComponent
escapeunescape
JSON.stringifyJSON.parse
toStrung(“base64”)Buffer.from(str,“base64”).toString()