イナヅマTVログ

[JavaScript] Cookieのためにどれ使う? escape, encodeURI, encodeURIComponent

| 0件のコメント

JavaScript で Cookie へ値を保存する時の文字列エスケープにどの関数を使うかの話。

Cookieを扱うJavaScript関数作成に、MDN(ja)を参考にコードを作ってみた。
https://developer.mozilla.org/ja/docs/DOM/document.cookie
ところが JSHint が盛大に警告を出してくる。
escape, unescape 関数がまずいらしい。

うろ覚えだけど escape じゃなくて encodeURI, encodeURIComponent 使えってどっかで見た覚えが。。。

まずは escape, encodeURI, encodeURIComponent の違いを調べてみた。

<div id="insert_area"></div>
var test_strings = [ "/", " ", ",", ".", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "-", "_", "+", "=", ":", ";", '"', "'", "<", ">", "?", "|", "\\", "~", "`", "foo;bar", "\x8F!!!" ],
    insert_area = document.getElementById( "insert_area"),
    insert_text = "",
    i = 0,
    limit = test_strings.length,
    raw_string = "",
    escape_string = "",
    encodeURI_string = "",
    encodeURIComponent_string = "",
    json_string = ""
;
insert_text += "<table>";
raw_string += "<tr><th>string</th>";
escape_string += "<tr><td>escape</td>";
encodeURI_string += "<tr><td>encodeURI</td>";
encodeURIComponent_string += "<tr><td>encodeURIComponent</td>";
json_string += "<tr><td>json</td>";
 
for( ; i < limit; i++ ) {
    var txt = test_strings[ i ];
    raw_string += "<th>" + txt + "</th>";
    escape_string += "<td>" + escape( txt ) + "</td>";
    encodeURI_string += "<td>" + encodeURI( txt ) + "</td>";
    encodeURIComponent_string += "<td>" + encodeURIComponent( txt ) + "</td>";
    json_string += "<td>" + JSON.stringify( txt ) + "</td>";
}
raw_string += "</tr>";
escape_string += "</tr>";
encodeURI_string += "</tr>";
encodeURIComponent_string += "</tr>";
json_string += "</tr>";
 
insert_text += raw_string + escape_string + encodeURI_string + encodeURIComponent_string + json_string;
 
insert_area.innerHTML = insert_text + "</table>";

【エスケープ不可文字】
escape: / . @ * – _ +

encodeURI: / , . @ ! # $ * ( ) – _ + = : ; ‘ ? ~ \x8F

encodeURIComponent: . ! * ( ) – _ ‘ ~

微妙に違うのね。
encodeURIComponentは優秀みたいだけど'(シングルクォート)を無視するのは手抜きな気がする。

Cookie保存するのにescapeじゃなくてencodeURIComponentへ変えても良いかがよくわからない。
Google先生に聞くと色々教えてくれた。

jquery-cookie のForum。
Use of encodeURIComponent() on cookie values should be escape()
jQuery プラグインの jquery-cookie 内部で encodeURIComponent を使ってるけど escape にしてくれないか。(だいぶ意訳)
みたいなスレッドが立っていました。

作者の回答は escape / unescape は deprecated だから encodeURIComponent 使ってるてことらしいです。
MDN: Deprecated and obsolete features

質問者の意図は encodeURIComponent を使って保存した Cookie を他言語で取り出して使えないから困るってことらしいのですが…

そっかだから MDN は使っちゃいけない escape 使ってるのかーなんて思ったりしました。

でもJSHintさんに怒られ続けながらescapeを使い続ける勇気も無くもう少し調べてみることにしました。

スレッドを追っかけてると stackoverflow: Why use encodeURIComponent() when writing json to a cookie へのリンクがあり JSON.stringify が使われていました。
単に"(ダブルクオート)で囲むだけみたいなのでどうなんでしょう…

同じく stackoverflow: Best practice: escape, or encodeURI / encodeURIComponent にこんなのありました。
そこでは escape は “Don’t use it, as it has been deprecated since ECMAScript v3.” と書いてあります。
jquery-cookie Forum 回答と同じです。
使っちゃだめなんですね escape。

escapeはダメ!encodeURIComponentを使う

jquery-cookie Forum スレッドの最後にファイナルアンサーがありました。
最初からちゃんと見とけば良かった。
そこにはMDN(en)へのリンクがあります。
https://developer.mozilla.org/en-US/docs/Web/API/document.cookie
日本語サイトと違うのはサンプルのコードがescapeを使わずencodeURIComponentに変わってたこと。

MDN(ja)のdocument.cookie記事のコードは古くメンテナンスされてなかったんですね。
はじめから本家を見ていればこんな遠回りもせずにすんだのに。

おかげで曖昧だったescape, encodeURI, encodeURIComponentのこと覚えられたから良しとします。
いつもMDNには助けられてるし。

でもJavaScriptで保存したCookieを他の言語で使うときどうする問題は未解決のままです。
どうするのが良いのですかね。

コメントを残す

必須欄は * がついています


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください