ここにはWebアプリ開発に共通し、言語に依存しないTipsや注意すべき点などを書きます。
関連ページ:Web言語比較 Webアプリに必要なHTMLの知識(実践編)
設計上の注意点
WEB+DB Press 2004/2 「システム設計の基礎知識」がとてもよい。
MVC
フレームワークを使う場合であれ使わない場合であれ、絶対にModel、View、Controllerを意識すること。
そうしないといつか必ずスパゲッティになる。
WebアプリにおけるMVCをシーケンス図で表すと次のようになる。
ブラウザ コントローラ モデル ビュー
→リクエスト
→データ操作依頼
←データ
-----→レスポンス生成依頼
←-----------レスポンス
MVCとは
PHPでMVC
なお、ASPからActiveX DLLを呼んだり、JSPからサーブレットクラスを呼び出すようなアーキテクチャを Model 1 という。
JSP における Model 1 と Model 2 アーキテクチャ
http://www.javaworld.com/javaworld/jw-12-1999/jw-12-ssj-jspmvc.html
GETとPOSTの使い分け
基本的に検索するときは検索条件を全部GETで渡す。
そうすればブラウザの「戻る」ボタンで戻れるし、検索結果をブックマークしておくことができる。
実際、ENではある画面のURL(クエリ文字列付き)をユーザにメールで送り、その画面に直接アクセスできるようにしている。
もしその画面へPOSTでデータを送っていたら、これは不可能になってしまう。
しかしURLが長くなりすぎる場合はどうするか?POSTを使うしかないだろう。しかたがない。
なお、下記のようなHTMLを書けばクエリ文字列とPOSTデータを同時に送信できるが、ブラウザによってはサポートしていないものもあるらしい(特に携帯電話)。
<form action = "?test=1234&name=Fermat" method = "POST">
<table>
<caption>GETとPOSTを同時送信</caption>
<tbody>
<tr><th>年齢[age]</th><td> <input type = "text" name = "age" value = "45"></td></tr>
<tr><th>名前[name]</th>< td><input type = "text" name = "name" value = "Gauss"></td></tr>
</tbody>
</table>
<input type = "submit" value = "送信">
</form>
ブラウザのリロードボタン
データを登録する画面などでブラウザの「リロード」ボタンを押してもデータが二重登録されないことが望ましい。
実現方法:
ワンタイムトークンを使う方法
入力画面→確認画面→(処理)→結果画面という構成にし、処理から結果へはリダイレクトする方法
(PRGパターンという名前がある:http://www.theserverside.com/tt/articles/article.tss?l=RedirectAfterPost a>
DBアクセスする際にすでにデータが登録されているか確認する方法
フレームワークによっては1.を組み込んでいる場合もある。
【PHP TIPS】 58. すごいリロード対策:ITpro
http://itpro.nikkeibp.co.jp/article/COLUMN/20070910/281585/
http://b.hatena.ne.jp/entrymobile/6210441
StrutsのsaveToken http://muimi.com/j/jakarta/struts/struts5.html
ブラウザの戻るボタン
ブラウザの「戻る」ボタンでちゃんと前の画面に戻れることが望ましい。
データ登録系の画面に戻ってもデータが二重登録されないことが望ましい。
ブラウザの閉じるボタン
window.onunload や window.onbeforeunload で閉じるボタンを押したイベントを捕まえられる。
http://q.hatena.ne.jp/1183615563
URL直打ち
URLを直接入力されたとき:
ログインしていない場合は別のページが表示されるか?
逆に特定の検索結果ページなどブックマークしておきたい場合:
ブックマークから飛んだとき、ブックマーク時点と同じ画面が表示されるか?
URLの長さの制限
RFCでは定められていないようだが、ブラウザやHTTPサーバごとに制限がある。
Apache は大体8KB。
[IE] URL に使用可能な文字数は最大 2,083 文字
http://support.microsoft.com/kb/208427/ja
Firefoxは100,000文字。
http://www.boutell.com/newfaq/misc/urllength.html
セキュリティ
クロスサイトスクリプティング
CSRF
Null-byte attack
SQLインジェクション
エラーが発生した場合でもサーバに関する情報は表示しないようにする。
レスポンスヘッダにHTTPサーバの名前とバージョンが出力される場合があるが、しない方がよい。
IPA セキュア・プログラミング講座 WEBプログラマコース
http://www.ipa.go.jp/security/awareness/vendor/programming/a00.html
安全なWebアプリ開発の鉄則2006 by 高木浩光
http://www.soi.wide.ad.jp/class/20060031/slides/43/
PHP と Web アプリケーションのセキュリティについてのメモ
http://www.asahi-net.or.jp/%7Ewv7y-kmr/memo/php_security.html#NullByteAttack
PHP のセキュリティ
http://memo.blogdns.net/phpsecurity.html
二重ログイン防止
例として、ログイン型の買い物サイトで、あるページにAさんが予約して
いた商品一覧が表示されているとします。ここでIEのCtrl+nなどで新しい
ウィンドウを開き、Bさんとしてログインします。
ここで、前者のウィンドウで一覧に出ている商品を「買う」ボタンをクリックすると、
その処理はBさんが行ったものと判定されます。
それどころか、それ以降も前者のウィンドウはBさんとしてログインしているものと
なります。
(2つのウィンドウでクッキーが共有されているため)
マネックスFX取引画面への2重ログイン防止機能追加について(2008年1月29日)/マネックス証券
http://www.monex.co.jp/AboutUs/00000000/guest/G800/new2008/news801o.htm
文字コード
WEB+DB Press Vol.9 2002/6に文字化け対策特集があります。
DBの文字コードは絶対Unicode。
昔の携帯電話はShift_JISしか表示できなかったが、2003年以降のものはたいていUTF-8も扱える。
画面遷移設計
画面遷移設計のよい記述方法は?
・GET,POST,linkを明記できること
・まずは手書きがベスト
・ファイルに落とすと結局strutsのコンフィグファイルと同じようなものになりそう
↓色わけするというアイディアはGood
http://gihyo.jp/dev/serial/01/piece/0004
画面設計
初期段階でHTMLだけのモックアップを作るとよい。
HTMLモックアップで最低限決めることは以下のとおり。
入力項目(ボタン、プルダウン、テキストボックス、ラジオボタン、チェックボックス等)
表示項目(表示データ)
ボタンやリンクの遷移先。遷移先で結果表示画面が必要ならそれも作る
プルダウンでは「未定」などNULLに相当する項目があるか。あるならそれもHTMLに書く。
プルダウンでは項目数を想定する。
検索結果画面やプルダウンなどリストになっているもののソート順
フレームについて
以下のことを
フレームのデメリット
検索エンジンからフレームの中のページへ直接アクセスしたとき、全体がわからない。
ブックマークしたとき、フレームの状態を完全に再現できない。
JavaScriptで他フレームを操作するとき、他フレームが完全に読み込まれていないとエラーになる。
frame要素は非推奨である。
1.については、業務システムでは関係ない。
2.については、PHPならやりようがある。
3.については、ユーザーに「ページが完全に読み込まれてから操作してください」と説明することでカバー可能。
リンクは絶対パスで
相対パスでリンクを張ると、forward(Java)やrequire(PHP)したとき困る場合があるので、全て絶対パスで統一した方がよい。
困る例:
+-1-index.php
+-2-a.php
+-b.php
a.phpから./b.phpとして相対リンクを張ると、index.phpからa.phpをrequireしたときb.phpへのリンクが使えなくなってしまう。
これはJava(JSP)など他の言語でも同じ。
絶対パスといっても、ホスト名などを直書きせず、getContextPath(Java)などの関数を使うこと。
参考:
http://oshiete1.goo.ne.jp/qa3199521.html
http://q.hatena.ne.jp/1151494223
ログ出力
ログ出力機能は絶対に必要。
ログレベルは
error(エラー。解決すべきもの)
warning(管理者に警告を発したいもの。必ずしも解決しなくてもよい。例:DBでロールバックしたとき毎回。)
info(通常動作のログ。例:「ログインしました」「ログアウトしました」「文書を承認申請しました」「メールを送信しました」)
debug(開発用。たとえば、全メソッド呼び出しのログや発行した全SQLのログを出力する)
くらいがよいか。
開発時は debug を使い、通常運用時は info を使う。
通常動作には興味がない管理者はwarningにする。
errorに設定することは滅多にない。
DBエラー
DBでエラーが発生した場合の処理。
予期しないエラーの場合の処理は共通化したい(ログを出力し、エラーページへ遷移するなど)
予期されたエラーの場合は個別に対応できるようにしたい
DBモジュールが例外を投げるのがベスト。
ユーザーインターフェイス
@IT:Webアプリケーションのユーザーインターフェイス
http://www.atmarkit.co.jp/fwcr/rensai/usability02/01.html
HTML
関連:Webアプリに必要なHTMLの知識(実践編)
HTMLの歴史と変遷
http://www.seo-equation.com/www/cat25/html_history
たまにはこんなものも興味深い…
form関連タグの重要性
Webプログラマにとってformやinput要素は非常に重要です。
少なくとも以下のタグについては、ちゃんとリファレンスを確認し、どんな属性があるかまできちんと理解しておきましょう。
form
input
textarea
select
option
text password checkbox radio submit/reset hidden
name(コントロール名) ○ ○ ○ ○ ○ ○
value(初期値) ○ ○ ○(ラベル) ○
size(コントロールの幅)○ ○ ○
tabindex(タブインデックス) ○ ○ ○ ○ ○
align(配置) ○ ○ ○ ○ ○
maxlength(文字列の長さの最大) ○ ○
disabled(無効化) ○ ○ ○ ○ ○
readonly(読み取り専用) ○ ○ ○ ○ ○
accesskey(アクセスキー) ○ ○ ○ ○ ○
checked(チェック済み) ○ ○
HTMLエスケープ、URLエンコードを使うべき局面
PHP FAQ: PHPとHTML
http://www.php.net/manual/ja/faq.html.php
を参照。
name,id,class属性の違いは?
タグにつける name,id,class属性。
これらはまったく異なる ものなので、ちゃんと使い方を理解しておきましょう。
name
フォームの input タグにこれをつけないとデータが送信されない。type="radio"かtype="checkbox"であれば、同じフォーム内で名前を共有することができる。それ以外のtypeに対して同じ名前をつけた場合、IEでは値が", "区切りで送られるようだ。
id
主にJavaScriptでDOMを操作するための名前。全タグ内で一意でなければならない。
class
CSSでスタイルを指定するための名前。同じスタイルを適用したいタグに共通の名前をつける。
JavaScript の観点からは name より id の方が便利。getElementById なら一発で要素を取得できるが、getElementsByName は複数個返ってくるため。
通常は
<input type="button" name="b1" id="b1" value="登録">
のように name、id 両方に同じ値を設定しておくのがベスト。
参考:
http://web.g.hatena.ne.jp/keyword/%E3%83%A1%E3%83%A2:class%E3%81%A8id
http://www.kanzaki.com/docs/html/htminfo12.html#S8
textareaのデフォルト値の書き方
次の書き方はNG。
<textarea>
abc
</textarea>
次のようにすること。
<textarea>abc</textarea>
formでsubmitして調べてみるとわかるが、前者だと改行や空白など余計なデータが送信されてしまう
optgroup や label タグ知ってますか?
optgroup タグは select によるプルダウンメニューを階層化する。
東京都
千葉県
神奈川県
埼玉県
大阪府
京都府
奈良県
兵庫県
http://www.kanzaki.com/docs/html/htminfo33.html
URIの中に&を書くべからず
<img src="http://hpcounter1.nifty.com/cgi-bin/counter.cgi?u=CQS02437&p=9&c=8">
これは駄目です。URI の中でも、& を書くときは & としなければなりません。
HTML において、& は CRO(文字実体参照開始区切り子)です。たとえば、< と書くと、これは "<" という文字に置換されます。
http://www.ne.jp/asahi/minazuki/bakera/html/opinion/ampersand
開発時のTips
ツールの利用
便利ソフト紹介 を参照。
テスト用のDBデータ
MySQLのmysqldumpでデータベースの状態を完全にエクスポート・インポートできる。
drop database hoge
create database hoge
インポート dump_20080328
を一発でやるシェルスクリプトを作っておき、
dump_20080328のように定期的にダンプをとっておいて、任意の時点のDBをいつでも再現できるようにしておくといいかも。
といってもデータ量が多い場合はimportにも時間がかかるけど。
文字化けテストのために
私は以下を「ばけもじ」という読みでIMEに登録して、テストの際はこれを入れるようにしている。
Abカナ漢字¥~-<i>&"'$①Ⅰ㍉ 覬鎹
今表示しているURLのソースを開く
IE版
Firefox版
hiddenタグのデータを表示するテクニック
<input name="hoge" type="hidden">
のようなやつを一時的に
<input name="hoge" type="text">
と書きかえると表示されます。
Firebug を使うよりもある意味お手軽です。
IE限定
スクリプトのエラーを通知する
[インターネットオプション]→「詳細」→「スクリプトエラーごとに通知する」にチェック。
これでJavaScriptのエラーを毎回通知される。
キャッシュを無効にする
[全般] - [設定] で、「保存しているページの新しいバージョンの確認」を「ページを表示するごとに確認する」に変更する。
これでリロードするたびに、キャッシュより新しいバージョンがあるかどうか確認するようになる。
「セキュリティ保護の為、アクティブコンテンツは表示されない」がうざい
メニュー[ツール]-[インターネットオプション]をクリック
↓
[インターネットオプション]ダイアログ-[詳細設定]タブをクリック
↓
[設定]-[セキュリティ]欄の、
[マイコンピュータでの、CDのアクティブコンテンツの実行を許可する]チェック
[マイコンピュータのファイルでのアクティブコンテンツの実行を許可する]チェック
をOnに
JavaScriptによる右クリック禁止対策
JavaScriptにより右クリックでのコンテキストメニューが禁止されている場合でも
右クリック→アラートが出ている間に右ボタンを押し、押しっぱなしにする→アラート閉じる
でポップアップメニューを出すことができる。
Firefox限定
メニューを消すのを禁止する
window.openでメニューを消されてしまうとなにかと不便なもの。
Firefox なら URL に about:config と入れて設定画面を出して
disable_window_open_feature
を変更すれば、メニューを消すのを禁止できます。
Firefoxでlocalhostにアクセスすると「権限がありません」というエラーになる
対処法は下記の通り。
for some time I had a strange problem; I could load sites from http://localhost in MSIE, but whenever I tried FireFox, it asked me for an user name and password. I've tried it all but I couldn't authenticate.
If you happen to have the same problem, here's a quick and simple workaround:
1: In Firefox type about:config in the addressbar
2: Find the preference named network.automatic-ntlm-auth.trusted-uris
3: Doubleclick and type localhost
4: Enter and you're done
参考リンク
HTML/CSSの仕様
HTML 4.01 仕様日本語訳
http://www.asahi-net.or.jp/%7Esd5a-ucd/rec-html401j/cover.html
Cascading Style Sheets, Level 2 (CSSの仕様日本語訳)
http://www.y-adagio.com/public/standards/tr_css2/toc.html
ブログでCSSを学ぶ人へ
http://mynotes.jp/blog/2007/05/to_someone_studying_css
勉強サイト
ごく簡単なHTMLの説明
とても厳密で詳しいサイト。
少なくとも「10. フォーム」だけは必ず読みましょう。
http://www.kanzaki.com/docs/htminfo.html
404や301などのHTTP Headerがどういう条件で出力されるかがわかる『http-headers-status』
HTTP/1.1でリクエストがとんだときにどういう条件でどういうヘッダーが出力されるかのフローチャートです。
http://www.ideaxidea.com/archives/2008/03/404301http_headerhttpheadersst.html