こんにちは、だいちゃんです。
先日、サイト上の挙動によってパラメータを出し分け、遷移先に引き継ぎ、また別のパラメータを付与して、引き継ぐ、、、という仕様のWebサイトを作成したのですが、日本語のままパラメータとして渡すとIEで動かないという現象に遭遇しました。
そもそも日本語のまま渡すのは問題がありそうだったので、あらかじめパーセントエンコーディングを済ませたものを用意したのですが、今後はChromeなどの主要ブラウザが自動的にデコードしてくれて(ありがた迷惑)遷移先のページで次のパラメータを付与する時に二重エンコードに繋がる危険がありました。
そこで、 取得したパラメータがエンコードされてるかをチェックして、処理をコントロールするJavascript関数 を作成しました。
今回の事例のように、エンコードされてるのか・されてないのか、環境によって変わってしまうため、どちらの状態で取得できているのかが不明な場合に有用かと思います。
また、今回の判定基準は結構ガバガバなので、あくまでも簡易的なチェックにしか向かないと思います。
ソースコードは下記の感じになりました。
// URI encode/decode
function ja2url(word, sw) {
// エンコード済みかの判定
if( word.match(/^%[\w]{2}.*$/) ){
if(sw == 'en'){
return word; // エンコード済・エンコード要求=そのまま返す
}else if(sw == 'de') {
return decodeURI(word); // エンコード済・デコード要求=デコードして返す
}
} else {
if(sw == 'en'){
return encodeURI(word); // エンコード未・エンコード要求=エンコードして返す
}else if(sw == 'de') {
return word; // エンコード未・デコード要求=そのまま返す
}
}
}
使い方としては、エンコード・デコードしたい文字列 と、 エンコードしたいのか・デコードしたいのか 、を引数にして関数に渡せば、あとはよしなに考えてお望みの形式で返してくれます。
エンコードしたいなら en
を、デコードしたいなら de
を第2引数として与えてください。
例)
var encoded = ja2url('沖縄', 'en');
console.log(encoded); // %E6%B2%96%E7%B8%84
まず、引数として入ってきた word がエンコードされているかどうかを match()メゾット を利用して、調べます。
パーセントエンコーディングの特徴(仕様)として、 %xx
(xは16進数の値)の形になるので ^%[\w]{2}.*
としています。
これでエンコード済みかどうかの目星を付け、次に第2引数で戻り値の形を検討します。エンコード済みで en
が指定されていればそのまま返し、エンコード済みで de
が指定されていればデコードして返してあげます。
エンコードとデコード自体の処理は、 Javascriptにあらかじめ用意されている関数 を利用しています。
日本語のようなマルチバイト文字に潜む罠は定期的に遭遇しますね(汗)