はりをきば

そこにピカマンがいる限り 私はテイッハットウッをやめない

【JavaScript】 ブックマークレットで%(余剰)使ったらハマった件

¯注意
この記事はを最後に更新されていない。
更新日が1年以上前の記事はリンク切れしていたり、情報としては役に立たなくなっている可能性あり。
ˆMixed Contentについて
この記事は投稿日が古い為、記事中の画像は非SSL(http://)で貼られている。(※投稿画像以外は全てSSL)
この件に関して詳しくはこちらを参照。

ブックマークレット作ってたらくだらない仕様にハマったのでメモ。


記事タイトル「javascript:スキームで%(余剰)使ったらハマった件」と
どっちにしようか迷ったがブックマークレット~の方がわかりやすいかな、と。
(大晦日に投下する今年最後の記事がこれっていうね。 ある意味私らしいといえば私らしい。)




例えば以下のコードがある。

function getHours12h() {
	var nd = new Date(),
	    AA = nd.getHours() < 12 ? "午前" : "午後",
	    gg = nd.getHours() % 12;
	alert(AA + gg + "時");
}


現在時刻を取得し、12h表示で現在の時間をアラートするだけ。




まずはこのまま実行してみる。

<a href="#" onclick="getHours12h()">getHours12h()</a>

getHours12h()


普通に実行できる。




次に、圧縮ツールに投下しインデント・空白・改行を削除、
関数名を削除し無名間数に丸めて実行してみる。

(function(){var nd=new Date(),AA=nd.getHours()<12?'午前':'午後',gg=nd.getHours()%12;alert(AA+gg+'時');})();
<a href="#" onclick="(function(){var nd=new Date(),AA=nd.getHours()<12?'午前':'午後',gg=nd.getHours()%12;alert(AA+gg+'時');})();">getHours12h (無名ver)</a>

getHours12h (無名ver)


ここまでは宜しい。問題は次。




↑のコードをjavascript:スキームで実行してみる。

<a href="javascript:(function(){var nd=new Date(),AA=nd.getHours()<12?'午前':'午後',gg=nd.getHours()%12;alert(AA+gg+'時');})();">getHours12h (javascriptスキーム)</a>

getHours12h (javascriptスキーム)


エラーになる。

  • IE11
    • f:id:Gutyan:20131231004201p:plain
  • Firefox
    • f:id:Gutyan:20131231004314p:plain
  • Chrome
    • f:id:Gutyan:20131231004328p:plain
  • Opera (Presto)
    • f:id:Gutyan:20131231004343p:plain

原因

記事タイトル見たらわかると思うが
原因はgetHours()%12;←この部分。
%12余剰演算ではなくパーセントエンコーディングとして解釈されてしまっている。

パーセントエンコーディング - Wikipedia

http://ja.wikipedia.org/wiki/%E3%83%91%E3%83%BC%E3%82%BB%E3%83%B3%E3%83%88%E3%82%A8%E3%83%B3%E3%82%B3%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0

どうすりゃいいの

余剰演算子の%と数字(今回は12)の間に手動で半角スペースを入れる。

<a href="javascript:(function(){var nd=new Date(),AA=nd.getHours()<12?'午前':'午後',gg=nd.getHours()% 12;alert(AA+gg+'時');})();">getHours12h (%修正)</a>

getHours12h (%修正)

半角スペースの部分はパーセントエンコードされても問題ない。
つまり、getHours()%%2012;のようになっても問題なく実行できる。
(%%2012なんてパッと見じゃ何の処理なのかわからんよね…)


こんなくっだらない罠に気づくのに数十分食われた自分が悔しい。
パーセントエンコード考えた奴と余剰演算子パーセントにした奴ぶっ飛ばしてえ。


ってか、この件ggっても一切情報がない。
余剰計算自体滅多に使われるもんじゃないけど
さすがに1人くらいは記事にしててもいいのでは…



余談

Operaのデバッガ便利すぎてやばい。
エラーの原因がパーセントエンコード誤解釈だと気づけたのは
OperaのコンソールがU+0012と表示してくれたから。


IEも何文字目が該当箇所なのか地味に書いてある。


それに比べFirefoxやChromeのデバッガは何なんだ。
Illegal Characterとか言われてもどこだかわかんねーっつーの。




…ところで、16進数での12(ASCII 0x12)って一体何の文字なんだ?
ってことでggったら、どうやら Device Control 2 という制御文字らしい。

C0 and C1 control codes - Wikipedia, the free encyclopedia

http://en.wikipedia.org/wiki/Device_Control_2

そんなこと知るか。