Chrome DevToolsのSnippets機能がすごい便利そう

[`evernote` not found]
[`livedoor` not found]
[`yahoo` not found]

フロントエンドエンジニア養成読本 [HTML、CSS、JavaScriptの基本から現場で役立つ技術まで満載! ] を読んで知ったのですが、ChromeのDevTools(開発者ツール)にはSnippetsという、コンソールでデバッグの際に使うスクリプトを保持してくれる機能があるようです。普段、よく使う機能でもConsoleパネルで打ち込んだりコピペしたりしてて面倒だなと思ってたのでこれは便利出す。早く知りたかったです・・・。

とりあえず、jQueryが読み込まれていないサイトでもjQueryが動くようにSnippetsに登録してみます。

ChromeのDev Toolsを開き(Ctrl+Shift+IかF12キーを押す)、Sourcesパネルを開いてその中のSnippetsタブをクリック。その後、左側の空白欄を右クリックしてメニューを表示し、その中の『New』をクリック。
snippets2

そうすると新しいsnippetが追加され、真ん中にコード記入欄ができるのでsnippetの名前を『jqueryfy』、コード下記のように記入し保存。

『フロントエンドエンジニア養成講座』に記載してあったコードには『else if』の内容は記載してありません。ただ、なぜかここのブログではjQueryはあるのに$がないといわれてしまうため、仕方なくelse ifを追加しています。

とりあえず、保存したsnippetを実行してみます。jqueryfyの箇所を右クリックしてメニューを表示し、『Run』をクリックするだけ。以下の画像は、当ブログで実行してみた結果です。
snippets3
当ブログの場合は、実行するとコンソール画面に『’$’ is jQuery 』と表示されます。通常のjQueryがないサイトでは『jQuery loaded! 』と表示されると思います(すでに、jQueryが動いているサイトでは実行されません)。

この他にも、下記ページに登録しておくと便利なスニペットがまとめてあります。
DevTools Snippets
思った以上に汎用性がありそうです。

フロントエンドエンジニア養成読本 [HTML、CSS、JavaScriptの基本から現場で役立つ技術まで満載! ] (Software Design plus)
フロントエンドエンジニア養成読本 [HTML、CSS、JavaScriptの基本から現場で役立つ技術まで満載! ] (Software Design plus)

Web開発者ツールのコマンドラインAPIが便利。色々と捗るぞ

[`evernote` not found]
[`livedoor` not found]
[`yahoo` not found]

ある日、あるページで、Chromeデベロッパーツールのコンソールを開き、「jQuery使ってるページかな?」なんて思って、『$』と入力してエンターキーを押すと、以下のような表示に。

コマンドラインAPI?? って何だ? 標準でjQueryみたいなことができるのか? と思いながら検索してでてきたのが以下のサイト。
Command Line API Reference – Chrome DevTools — Google Developers

元々Firebugについていた機能なようなのですが、Chromeのデベロッパーツールにもついているそうです。
というわけで、高校の英語の授業では成績順にA,B,Cクラスと分かれていてずっとCクラスだった自分、そして大学の英語の必須授業はさっぱり分からずに危うく単位を落としかけたほどの自分(ほとんど出席加点だと思われます)が、上記英語のページを読み取っていろいろ調べてみました。

とりあえず、今回のために下記ページを用意。
コマンドラインAPI用テスト用ページ
ついでに、IE11のF12開発者ツールやFirebugでも動くかどうかも検証しておきました。

$(selector)

IE11:☓ Firebug:◯
document.querySelectorと同義なよう。jQueryを使ってるサイトで使うと、jQueryオブジェクトが生成されるので注意。IE11では、document.getElementByIDと同義なよう。
テスト用ページで、$(‘li’)とすると、下記のような結果となる。
consoleapi-$

$$(selector)

IE11:◯ Firebug:◯
document.querySelectorAll()と同義なよう。$$(selector)[0]は$(selector)と同じなはず。
テスト用ページで、$$(‘li’)とすると、下記のような結果となる。
consoleapi-$$

$_

IE11:☓ Firebug:◯
直前に実行した式をあらわすよう。
例えば、今回用意したテスト用ページで、$$(‘li’)とした後、$_.lengthとすると、下記のような結果となる。
consoleapi-$_
ただ、正直こんなことをするぐらいなら、上矢印キーを押すと『$$(‘li’)』と表示されるので、その後に『.length』としたほうがいいような気もしなくはない。

$0 – $4

IE11:◯ Firebug:◯
最近Elementsタブで選択した要素をあらわすよう(ついでに$9まで実装すればよかったと思うのだけれども、なんで$4までにしたのだろ?)。
例えば、テスト用ページにおいてElementsタブで虫眼鏡のようなボタンを選択した後、ブラウザの『Google』という箇所をクリックして、コンソール画面で$0と入力してエンターキーを押すと下記のような結果となる。
consoleapi-$0
これは本当に便利です。$0ぐらいしか使わないと思いますが、本当に便利。
ちなみに、jQueryを使っている環境で、『$($0)』とすると、直前に選択した要素をjQueryオブジェクトとして取得できます。
consoleapi-$0-jQuery
上記の!function()以降5行は、jQueryを使っていないページでも、jQueryを使えるようにjQueryを読み込む方法です。
参考:Chrome の userscript (とConsole)で jQuery を使う方法 – 弘法にも筆の誤り

$x(path)

IE11:☓ Firebug:◯
XPathという構文を用いて要素を取得するよう。
例えば、テストページにおいて、『$x(“//li[a]”)』とすると下記のようになる。
consoleapi-$x
上記は、aタグを子要素にもつliタグをあらわす。
ただ、自分がXPathというものをよく分かってないので、詳しくは分かりません。以下のリンク先を参考にしてください。
XML Path Language – Wikipedia
XPath
特定の子要素を持っている要素を選択できるのはよさそうだけど、大概のことは$$()で事足りそうな気はする。

clear()

IE11:☓ Firebug:◯
コンソールのクリア。特に説明もいらないと思うし、特別役に立つというわけでもないので、詳細は省きます。

copy(object)

IE11:☓ Firebug:◯
引数に指定した式の実行結果をクリップボードに入れてるよう。
例えば、テストページにおいて『グーグル』という文字を選択した後に、『copy($0)』として実行した後、CtrlキーとVキーを押してペーストすると下記のような結果となる。
consoleapi-copy
Firebugだと、クリップボード内に”[object XrayWrapper [object HTMLLIElement]]”という文字列が入るよう。微妙に動作が異なるようです。

dir(object)

IE11:◯ Firebug:◯
引数にいれたオブジェクトのプロパティをすべて列挙してくれるよう。
例えば、『dir($$)』とすると以下のような感じに。
consoleapi-dir
これは面白い。『dir(window)』なんてしたら新しい発見があるかも?

dirxml(object)

IE11:☓ Firebug:◯
DOM要素など、XMLで表示できるオブジェクトをいれると、そのXMLを表示するAPIだと思われます。
例えば、テストページにおいて、『dirxml($$(‘body’)[0])』とすると以下の様な結果に。
consoleapi-dirxml
DOM要素だといまいちいい使い道が思いつかないけど、多分なにかいい使い方がるんじゃないかと思われます。

inspect(object)

IE11:☓ Firebug:◯
引数にいれたDOMオブジェクトを指定したエレメント画面に飛ぶようです。
例えば、コンソール画面で『inspect($$(‘body’)[0])』として実行すると、bodyタグを指定した状態のエレメントタブに飛びます。

getEventListeners(object)

IE11:☓ Firebug:◯
オブジェクトに登録したイベントが分かるよう。
正直、コマンドラインAPIを調べて一番ビックリしたのがこの機能。今回はこの関数用に別のテスト用ページを用意しました。
コマンドラインAPI用テスト用ページ2
上記ページは以下のようなコードとなっています。

HTML

JavaScript

ボタンが3つあり、上からonclickでアラートを表示するように指定、addEventListenerでクリックしたらアラートを表示するように指定、jQueryを用いてクリックしたらアラートを表示するように指定。というようになっています。

onclickでイベントを指定した要素を見てみると、以下のようになりました。
consoleapi-getEventListeners-onclick
Objectというオブジェクトがあると思うのでクリックしていくとlistenerというプロパティ名があり、そこに登録したイベント関数が書かれています。普通に表示すると最初の1行しか表示されませんが、マウスをあてるとツールチップとして関数の中身が表示されます(画像ではマウスが表示されてないので分かりにくいですが、右下の『function onclick(event){ alert(‘onclick’) }』と書かれた枠です)。

addEventListenerの場合か以下のような感じ。
consoleapi-getEventListeners-addEventListener
これで、どういう仕組みで動いているのか分からないイベントもすぐに分かるようになるかもしれません。

と思って、jQueryで登録したものを見ていると以下の様な感じに。
consoleapi-getEventListeners-jQuery
イベント内容は、『function (a){return typeof f!=”undefined”&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b}』としか表示されず、実際に登録した『alert(“jQuery Event”);』という文字はどこにも書かれていません。
jQueryで登録したイベントはうまく見ることができなさそう。何かいい方法はないものだろうか。

keys(object) values(object)

IE11:☓ Firebug:◯
引数にいれたオブジェクトのキーと値が一覧として表示されるよう。
実行結果は以下の様な感じに。
consoleapi-keys-values
for in文を使わずにすむという感じかな。

monitorEvents(object[, events]) unmonitorEvents(object[, events])

IE11:☓ Firebug:◯
引数にいれたオブジェクトにイベントが発生すると、そのイベントを監視してコンソール画面にそのイベントの結果が表示されるよう。unmonitorEventsでその監視を止めるらしい。
実行結果は以下の様な感じ。
consoleapi-monitorEvents
monitorEventsでwindowのマウスイベントを監視するようにし、unmonitorEventsでmousemoveのみ監視対象から外した結果です。確かに、unmonitorEventsを実行した後は、mousemoveのイベント結果は表示されてませんね。

profile([name]) profileEnd([name])

IE11:☓ Firebug:◯
関数などの解析を行うためのメソッドらしい。
profileを解析したい処理の前に実行し、profileEndで解析を終了するよう。
実行結果は以下の様な感じ。
consoleapi-profile
‘hoge’というリンクをクリックすると、profiles画面に。
consoleapi-profile2
・・・。
すみません。例が悪かったかもしれませんが、よく分かりません。とりあえず、profileメソッドを使った間のCPUの状況をみているようなのですが・・・。勉強不足です。

なお、今回IE11のF12開発者ツールにはないと書いたメソッドでも、コンソールAPIとしては提供されているものもあるようです(console.dirなど)。

JavaScriptのみの入力文字チェックはダメ。という話

[`evernote` not found]
[`livedoor` not found]
[`yahoo` not found]

前回(HTMLのvalue値は、Web開発者ツールで簡単に変更できるという話 | while(isプログラマ))の続き。

テキスト入力項目の制限
前回予告したとおり、今回は上記のページから、半角数値以外の文字を送信するという話です。
JavaScriptでの入力項目チェックのスクリプトは以下のようになっています。ソースコードに書いてある内容と同じなので、ユーザーでも簡単に分かります。

簡単に説明すると、二行目でフォームが送信されるときに設定する関数を設定しています。
4行目で半角数値のみの文字かチェックし、そうでなければアラートをだして送信を取りやめています。

今回は上記のフォームから、半角数値以外の文字が入った文字列を送信する方法を二つ紹介。

その1

POST渡しというものは、フォーム自体のnameはみていません。それを利用して、もう一つフォームを作成してそのフォームから送信するという方法が考えられます。
Web開発者ツールを開いてコンソールモードにした後、コンソール画面に下記のように入力して、エンターキーを押します。

はい。これで『aiueo』という文字を送信できましたね。リファラチェックにも引っかかりません。

何をやっているかというと、新しいフォームのjQueryオブジェクトを作成し、その中にnameがOnlyNumのinputタグをいれ、トリガー関数でサブミットしているというものです。
これだけじゃあ何をやっているのか分からない人もいると思うので、試しに『trigger(‘submit’)』の箇所を変更して、下記のようにしてみてください。

insertAfterは、対象要素をinsertAfter関数内で指定した要素の後に追加する関数です。すなわち今回の場合だと、現在あるformタグの後に、新しく作成したformがDOM上に追加されることになります。
なので、上記を実行すると、下記の画像のように、今あるテキストボックスの下にテキストボックスが追加されたはずです。
テキストボックスを追加
そして追加されたテキストボックスをフォーカスし、エンターキーを押すと、半角数値以外の文字が送信されてしまうというわけです。

なお、今回はサブミットする時に値をチェックする関数をbindで指定していますが、liveでやるとうまくいきません(キリッ)。と書こうとおもったんですが、どうやらlive関数は、submitでイベントハンドラが登録できないようです(参考:jQueryのlive関数が超便利な件について | さくらたんどっとびーず)。まあ、live関数の仕組みを考えたら、そりゃそうか(liveは、$(document)に対してイベント設定し、バブリングを見て実行するかどうか決めているそうなので)。

その2

その2は、フォーム送信時の値チェックのイベント自体をキャンセルする方法です。
bindで設定したイベントはunbind関数で削除できてしまうので、Web開発者ツールのコンソールで下記のように記入して実行するとイベントが起きなくなってしまいます。

こちらのほうが直感的ですし簡単ですね。ただ、自分がunbind関数を今まで使ったことがなかったので最初、思いつきませんでした。

で、思いつかないといえばもうひとつ。ある意味自分にとって当たり前になっていたので気づかなかったのですが、ふと思ったことがあります。
先日の入力制限も、今回の入力チェックも、
JavaScriptをオフにしてたら半角数値以外でも送信しちゃうんじゃね?・・・と。

では、早速試してみましょう。ChromeからJavaScriptを簡単にオフにするアドオンを以下からインストールします。
Chrome ウェブストア – jsoff
インストールしたらブラウザの右上にサイのマークがついたボタンが追加されていると思うので、それをクリック。『Zzz』となったら、JavaScriptがオフになっているという意味です。
つづいて先日の入力制限用フォームのページと、今回の入力チェックのテキスト入力項目の制限のページへ。
 
結論:どちらも普通に半角数値以外の文字を入力して送信できた。

たまには、JavaScriptがオフになっている状況も考えたほうがいいかもしれませんね。

HTMLのvalue値は、Web開発者ツールで簡単に変更できるという話

[`evernote` not found]
[`livedoor` not found]
[`yahoo` not found]

うちの会社の話です。ある会員用ウェブサイトにおいて、ログイン後のページではその会員のIDをinputタグをhiddenにして保持するという方法をとり、全ページPOSTで送信するようにして、それぞれのページで会員の情報を得るという手法をとっていたのですが、これだとログイン後、inputタグのhidden内のIDだけを書き換えると、簡単に他の会員の情報が見えてしまうということが発覚しました。

他にも、3種類の選択肢が用意されているセレクトボックスがあったのですが、それぞれのoptionタグのvalue値は、『2』『3』『4』というようなものでした(実際は少し違うのですが、こんな感じです)。気になる人は気になると思いますが、なぜ『1』がなく、2からなのかと。そこで、optionタグのvalue値、例えば現在『2』となっているvalue値を『1』と書き換え、その箇所を選択すると・・・。なんと、その会員には見せてはいけない情報がズラリ。

上記は上司や先輩社員に報告することにより解決に至ったのですが、その時の上司や先輩社員の反応は、「えっ? そんなことできるの?」という感じをうけました。「GET渡しからPOST渡しに変更したうえに、リファラチェックしてるんだよ?」という感じで(注:あくまで自分の勝手なイメージです)。
結論からいうと、簡単にできます。ブラウザに付属のWeb開発者ツールをつかえば。Web開発者ツールとは、IE(8以上)では『F12 開発者ツール』、Chromeでは『Developer Tools』、Firefoxでは『開発ツール』と呼ばれてるものです(Firefoxはむしろ、『Firebug』のほうが有名ですが、Firebugはアドオンをインストール必要があり、『開発ツール』は標準で付属しているという違いがあります。機能面でいえば『Firebug』のほうが多いので、ウェブ制作に関わってる人なら『Firebug』をインストールしたほうがいいと思われます)。

では、その方法を簡単に説明します。
今回は、サンプルとして前回のHTMLのテキストボックスを、できるかぎり半角数値のキー入力のみにするで作成した半角数値しか入力できないようにしたテキストボックスから数値以外のテキストを入力し、送信する方法を三種類ご紹介。
 
下記ページが今回利用するページです。
テキスト入力項目の制限
HTMLとJavaScriptとPHPは下記のようになっています。

HTML

JavaScript

PHP

HTMLとJavaScript側では、数値以外の値が入力できないようなテキストボックスを用意しています。formタグ内のテキストボックス内でエンターキーを押すと、フォームを送信するという仕様を利用して、エンターキーを押すと同じページに送信するようにしています。
PHP側では、POSTで渡されたOnlyNumの値をみて、数値かどうか判定しています(7行目)。特別今回の記事に必要なわけではありませんが、5行目でリファラと自身のページの情報をチェックし、同じかどうかを判定しています。

まずは開発者ツールの表示方法を説明。ChromeかIEかFirebugならF12キーを、Firefoxの開発者ツールならCtrl+Shift+Iキーを押してみてください。すると、ブラウザの下にHTMLのDOMツリーが書かれたツールが表示されると思います。これが開発者ツールです。以下、画像はChromeのDeveloper Toolsです。
Chrome Developer Tools
このDOMツリーはソースコード(Ctrl+U で表示したソース)と全く同じというわけではなく、JavaScriptで変更したものが反映された結果となっています(その他にも、DOMツリーの仕様にしたがって変更されていることがあります)。
以下、このWeb開発者ツールを使って数値のみの入力制限をしているテキストボックスに数値以外を入れる方法を、三種類説明します。

その1

1つ目の方法は、入力制限を取り除く方法です。
まず、Chromeだと左下の虫眼鏡のようなアイコン、IEやFirefoxだと左上の矢印のアイコンをクリックし、その後にテキストボックスをクリックしてみてください。そうすると、開発者ツールの中のDOMツリーが、テキストボックスの箇所を選択した状態となります。
Chrome Developer Tools

つづいて、テキストボックス中の、onkeydown属性の中、『return OnlyNumber(event)』をダブルクリックするとその箇所が編集できるようになるので、onkeydown属性の中身を削除してください。
Chrome Developer Tools
これで、テキストボックスの中に数値以外の値が入力できるようになりました。試しに、『aiueo』と入力してエンターキーを押した結果は以下のようになります(style属性の中を削除するとIEとFirefoxで全角を入力できるようになり、oncontextmenu属性の中を削除すると右クリックしてメニューを表示させることができるようになります)。
数値以外を入力した場合の結果

その2

2つ目の方法は、ツール内で直接、値を入力する方法です。
テキストボックスの要素を選択してそのコード上で右クリックします。すると、メニューが表示されるので、Chromeでは『Add Attribute』、IEでは『属性の追加』、Firebugでは『新規属性』をクリックしてください。
Chrome Developer Tools

すると、入力ボックスがでてくると思うので、そこに『value=”aiueo”』などとして、value属性を追加し、その中に文字を入力してみてください。(Firefoxの開発者ツールでは属性を追加するという項目はないよう。仕方がないので、適当にどこか(例えば、『autocomplete=”off”』上)でダブルクリックし、そのテキスト入力項目内の最後に『value=”aiueo”』と追加してみてください)。
Chrome Developer Tools

上記の作業をすることにより、ブラウザ上のテキストボックスにもvalue属性にいれた文字が入るはずです。その状態でテキストボックスにフォーカスをあてたあと、エンターキーを押すことによって数値でない値が送信されます。
数値以外を入力した場合の結果

その3

3つ目の方法は、コンソールを使う方法。ちょっとだけ難しくなりますが、JavaScriptが分かるのであれば難しくありません。
まず、開発者ツールの上部にある『Console』もしくは『コンソール』タブをクリックしてみてください。すると、開発者ツール内がコンソールモードに切り替わります。
そしてそのコンソール内に、『document.querySelector(‘input’).value=”aiueo”』と入力して、エンターキーを押してみてください(querySelectorについては、右記を参考:document.querySelector – Web API リファレンス | MDN)。
Chrome Developer Tools

すると、テキストボックス内に『aiueo』と入力された状態になるので、先ほどと同じく、テキストボックスにフォーカスをあてて、エンターキーを押します。すると、数値でない『aiueo』という値が送信されます。
数値以外を入力した場合の結果
ところで、ChromeとFirefoxのWeb開発者ツールにはコマンドラインAPIというものが用意されており、その1やその2でしたように、テキストボックスの要素を選択状態にした後、コンソール画面にいって『$0.value=”aiueo”』としても同じ動作をします。この$0というのがコマンドラインAPIで、$0は直前で選択した要素を返すAPIとなっています。コマンドラインAPIについてはそのうち書くかもしれません。

以上、inputタグ内のvalue値を変更する方法を3つ紹介しました。これ以外にもあるかもしれませんが、思いつくかぎり3つです。
もちろん、上記で紹介した方法はinputタグ内のvalue値を変更する方法以外にも利用できます。例えば、style属性を追加してレイアウトを変更することもできますし、onclick属性を追加して新たにクリックした時に発生するイベントを追加することも簡単にできます。
いろいろ気になった箇所を変更してみると、新たに脆弱性が発見できるかもしれませんね。mixiでは脆弱性報告制度なんてものができたので、これでお小遣いを増やすこともできるかも? (参考:脆弱性報告制度 << mixi Developer Center (ミクシィ デベロッパーセンター))
まあ、さすがにmixiぐらいの規模のサイトが、こんな簡単に変更できるような脆弱性を持ち合わせているとは思いませんが(あえて、『思いたくありませんが』とは書いてません・・・)。

以下、応用問題。
今回のサンプルで、送信前にJavaScriptで半角数値かどうかのチェックをいれたら、半角数値以外の値を送ることはできないんじゃないか? なんて思われた方もいるかと思いますが、そんなことはありません。
それ用のサンプルページも作ってみました:テキスト入力項目のチェック
今回はjQeuryを外部JavaScriptとして呼び出すようにし、JavaScriptのコードは以下のように変更しています。

簡単に説明すると、フォーム送信時にテキストボックス内が半角数値かどうかチェックして、半角数値でなければアラートを出して注意を促し、送信しないという動作になっています(実は言うとこのコードでは何も入力しないと送信してしまうのですが、あくまで半角数値以外の値を入力することを考えてみてください)。

上記のページでどうやって数値以外の値を送信するかは次回説明しようと思います。