canvasで描いた絵をバイナリ形式でサーバーにPOST送信する方法

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

最近、自宅で時間ができるとHTML5 テクニックバイブルという本を読んでいるのですが、初めて知ったことがいろいろ書いてあって驚愕する日々を送っています。

今回は上記書籍を読んで知ったCanvasで描いた絵を、Base64のData URI形式ではなく、バイナリ形式にしてPOST送信する方法のメモ。ただし、IE9では使えないよう。

まずは、受け取り側のPHPを記述。普通にフォームの画像ファイルを受け取ってサーバーにファイルを保存するような記述を書いておきます。ファイルのアップロード | PHP Laboを参考にしました。

上記のPHPでは、acceptImageというプロパティに対応するファイルをtest.pngという名前で保存するようにしたPHPです。試しに、下記のようなHTMLを書いて普通にファイル選択してPOSTするとうまく動きました。

というわけでつづいて、前に作ったCanvasお絵描きツールの投稿先を、上記PHPに変更し、JavaScriptでCanvasのデータをPOST渡しできるよう記述するように投稿ボタンを押した時の処理を下記のようにしてみました。

実行サンプル:canvasを使ったお絵描き投稿システム

HTML5 テクニックバイブルのほうでは、jQueryを使わずに純粋にXMLHttpRequestオブジェクトを使ってAjax送信しているコードが載っていたのですが、自分は最近Ajaxを使う時はjQueryを使うことにしてるので、jQueryを使って書いてみました。実はjQueryを使ったAajxでは最初うまく動かなかったのですが、調べてみるとjQueryでFormDataオブジェクトをAjaxで送信する場合には、contentTypeとprocessDataをfalseにしなければいけないと分かり、そのオプションを変更することによってうまく動きました(参考:jQuery: FormData オブジェクトで送信する – Sarabande.jp)。
HTML5テクニックバイブルに載っているコードでは、そんな記述が必要ない分、もう少しシンプルな記述となっています。

それにしても、上記コードは自分が初めて知ることがたくさんあります。FormDataオブジェクトぐらいなら聞いたことはあったのですが、BlobオブジェクトとかArrayBufferオブジェクトとかUint8Arrayオブジェクトとか、何だそれ!? という思いです。簡単に説明すると、BlobオブジェクトはMIMEタイプを含んだバイナリデータを表し、ArrayBufferオブジェクトは固定長のバイナリデータを表し、Uint8Arrayは8ビットの符号なし整数を表すようです。なお、Uint8Arrayの説明には、C言語での同等タイプに『uint8_t』という記述が。そんなデータ型がC言語にあったか? と思って調べてみると、どうやら『unsinged char』と同じらしいです(参考:整数型 – Wikipedia)。

HTML5はある程度知っているつもりでいましたが、まだまだ知らないことが多くありそうです。

ところで、Blobオブジェクトの取得については、canvasオブジェクトにtoBlobメソッドが実装されていれば、そのメソッドを使うことにより、簡単に取得できるようです。ただ、このメソッドは残念ながら、Firefoxでしか実装されていないよう。html5.jpによると、2011年4月5日の草案にはすでに提案されていたようなんですが・・・(参考:W3C – 『HTML 5 differences from HTML 4』日本語訳 – HTML5.JP)。Chromeですら実装してないとなると、さすがに使うのに躊躇します。

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のテキストボックスを、できるかぎり半角数値のキー入力のみにする

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

HTMLのフォームのテキストボックスに、数値のみのキー入力してほしくないということもあると思いますが、そういう時のための実装を考えてみたので紹介。

HTML

JavaScript

続きを読む

dtタグをクリックすると隣接するddタグをスライドして開閉する方法(jQuery利用)+α

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

放置していたサイトをリニューアルしようとjQueryを勉強しています(プロバイダのサーバーで運用してたんですが、容量も少ないし、CGI動かすとなると別ドメインになるしとあまりよくないので、ここのドメインのサブドメインにして移転しようと思っています)。

というわけで今回はjQueryについて。用語や名前を意味するdtタグをクリックすると、その下のddタグを開閉させる方法についてです。まず、最初にページを開いた時にはddタグは閉じているものとします。

実行例

冬の次の季節
春の次の季節
夏の次の季節
秋の次の季節

終わり。

としたいところですが、これだけでは何なのでもう少し改良してみます。
 URIにアンカー(ハッシュ)があると、ページを開いた時にアンカーに対応するdtタグの下のddタグを開くというものです。

実行例

右手
お箸を持つ方の手
左手
お箸を持たない方の手

右手
多分これでうまくいくはず。

なぜかここでやったら、dtタグじゃなくて、ddタグのほうにページが遷移しました。なんでだろう・・・。

navigatorオブジェクトによるブラウザ識別まとめ

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

JavaScriptには、navigatorオブジェクトという、ブラウザ等の利用環境を識別するオブジェクトがあります。なんとなく気になったので、”appCodeName”と”appName”と”appVersion”と”userAgent”をそれぞれのブラウザで見たときの動作を、バージョンなどバラバラですが、調べれた分だけまとめてみました。なお、appVersionやuserAgentのかっこ内は、利用しているパソコンの環境によっても異なることがあります。

appCodeName
appName
appVersion
userAgent
IE6 Mozilla
Microsoft Internet Explorer
4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
IE7
(IE9の開発者ツール使用時)
Mozilla
Microsoft Internet Explorer
4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; HPDTDF; BRI/2; .NET4.0C; .NET4.0E)
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; HPDTDF; BRI/2; .NET4.0C; .NET4.0E)
IE8 Mozilla
Microsoft Internet Explorer
4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; BTRS122159; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 1.1.4322)
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; BTRS122159; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 1.1.4322)
IE9 Mozilla
Microsoft Internet Explorer
5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; HPDTDF; BRI/2; .NET4.0C; .NET4.0E)
Firefox4.0.1 Mozilla
Netscape
5.0 (Windows)
Mozilla/5.0 (Windows NT 5.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
Firefox9.0.1 Mozilla
Netscape
5.0 (Windows)
Mozilla/5.0 (Windows NT 5.1; rv:9.0.1) Gecko/20100101 Firefox/9.0.1
Chrome12.0.742.122 Mozilla
Netscape
5.0 (Windows NT 5.1) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.122 Safari/534.30
Mozilla/5.0 (Windows NT 5.1) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.122 Safari/534.30
Chrome16.0.912.75 Mozilla
Netscape
5.0 (Windows NT 5.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.75 Safari/535.7
Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.75 Safari/535.7
Safari5.0.5 Mozilla
Netscape
5.0 (Windows NT 5.1) AppleWebKit/534.52.7 (KHTML, like Gecko) Version/5.1.2 Safari/534.52.7
Mozilla/5.0 (Windows; U; Windows NT 5.1; ja-JP) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1
Safari5.1.2 Mozilla
Netscape
5.0 (Windows; U; Windows NT 5.1; ja-JP) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1
Mozilla/5.0 (Windows NT 5.1) AppleWebKit/534.52.7 (KHTML, like Gecko) Version/5.1.2 Safari/534.52.7
Opera11.11 Mozilla
Opera
9.80 (Windows NT 5.1; U; ja)
Opera/9.80 (Windows NT 5.1; U; ja) Presto/2.8.131 Version/11.11
Opera11.60 Mozilla
Opera
9.80 (Windows NT 5.1; U; ja)
Opera/9.80 (Windows NT 6.1; U; ja) Presto/2.10.229 Version/11.60
あなたの環境

appCodeNameはいったいなんなんでしょう。ブラウザのコードネームを示すそうなのですが、全部”Mozilla”って・・・。多分中には、”Mozilla”以外を返すものもあるのでしょう。
 ところで、パッと見userAgentを見たら何のブラウザを使ってるか判別できそうですが、どうもこの値は偽装できてしまうそうです。でも、userAgentを使わなかったら、Firefoxを判別できない・・・。

これで終わるのはなんなので簡単に、navigatorオブジェクトを見てリンク先を変える関数作ってみた。

使用例

クリック!

第三引数に、navigatorオブジェクトの検索結果、第一引数に真だった時のリンク先。第二引数に偽だった時のリンク先。ものすごい、使う人にとって親切じゃない関数! もっと使いやすい関数が書けるようになりたい。後、変数名もうまくつけれるよになりたい・・・

応用例

クリック!

まどろっこしいにもほどがある!!

余談ですが、WordPressが勝手に'(シングルクォテーション)を”(ダブルクォテーション)に変換するので困りました。上記の”クリック!”というリンクはJavaScriptで制御しています。