ステーキの戯れ言

私のブログです。アドベントカレンダーを埋めるために作りました。

URLエンコードで半角スペースがやらかす

解決法?

 デコードする前に先に+を半角スペースに置換してしまえばいい。
 そしてdecodeURIComponentを使ってデコードする。%がついていないやつはスルーしてくれた。






 論文でもブログでも、最初に結論を書いてしまえばいいのさ。






 
 URLエンコードについて、自分の書いたプログラム内でこれ何だ?って悩んでしまったので、次は忘れないようにちゃんと書いておこう。
 環境はnode.jsでjavascript

URLエンコードって?

 日本語や記号とかを%○○って感じでエンコードするやつ。htmlでformタグ使ってpostした時に、これで変換して送ってくる。ちなみに元に戻すことをデコードっていうんだぜ!

で?

 javascriptではencodeURIComponentでURLエンコード、decodeURIComponentでデコードしてくれる。

let Data = "あいaiueoうえお";
let EncodeData = encodeURIComponent(Data);
let DecodeData = decodeURIComponent(EncodeData);
console.log(Data);
console.log(EncodeData);
console.log(DecodeData);

こうなる
f:id:uragou:20180316022518p:plain
 encodeURIとdecodeURIもあるけど、こいつら「=」をちゃんと処理してくれなかった。



ここからが問題

 htmlでformタグ使ってpostすると半角スペースを「+」に変換してしまう。
f:id:uragou:20180316021754p:plain
これを

 %E3%81%82+%E3%81%84+%E3%81%86+%E3%81%88+%E3%81%8A 

にしてしまう。
%○○にせず+にしてしまうのでデコードできない

let DecodeData = decodeURIComponent("%E3%81%82+%E3%81%84+%E3%81%86+%E3%81%88+%E3%81%8A");
let DecodeData2 = decodeURI("%E3%81%82+%E3%81%84+%E3%81%86+%E3%81%88+%E3%81%8A");

console.log("Componentつき");
console.log(DecodeData);
console.log("\nComponentなし");
console.log(DecodeData2);

f:id:uragou:20180316022523p:plain
これじゃあ良くない。

とりあえずの解決法

 正規表現とかにつかうreplaceを使った。%○○になっていない部分はスルーしてくれたので(もともと英字とかはそのままだったし)デコードするまえにreplaceを使って「+」を半角スペースに変換してやればいい、いわばちょっとしたひと手間てきなもの。
 ちなみに日本語だと%○○%○○%○○で一文字表しているっぽいので、この間に何か挿入するとデコード自体出来なくなる。置換なら形式を崩さないのでOK。

let Data = "%E3%81%82+%E3%81%84+%E3%81%86+%E3%81%88+%E3%81%8A"
Data = Data.replace(/\+/g," ");
let DecodeData = decodeURIComponent(Data);
let DecodeData2 = decodeURI(Data);
console.log(Data);
console.log("Componentつき");
console.log(DecodeData);
console.log("\nComponentなし");
console.log(DecodeData2);


f:id:uragou:20180316024434p:plain
こうなる。
replaceは 変数.replace(変換前,変換後);って感じで記述する。
/ /で囲ったのは正規表現となり、「+」は何か意味を持っている感じがするので「\」をつける。
gはオプションで、これをつけないと文字列内の一番最初にマッチした部分しか変換してくれない。

じゃあもともと+のやつは?

 htmlでformタグ使ってpostした時は「%2B」になってくれるので、デコード前に置換すれば問題ない。
 ただencodeURIは+を変換してくれない。


ていうかもともとの形にそって、半角スペースは%20に置換してもいいと思う。

最後に

 一応問題は解決したけど、これ絶対もっといい方法あるだろ。