diff --git a/ja/04.0.md b/ja/04.0.md index 328d854f..7f95355c 100644 --- a/ja/04.0.md +++ b/ja/04.0.md @@ -1,6 +1,6 @@ # 4 フォーム -フォームは我々が普段Webアプリケーションを書く時によく使うツールです。フォームを通して便利にユーザにサーバとデータをやり取りさせることができます。以前にWeb開発をしたことのあるユーザにとってはフォームはとてもお馴染みのものです。しかしC/C++のプログラマからすると、少々ばかり門外漢かもしれません。フォームとは一体何でしょうか? +フォームは普段Webアプリケーションを書く時によく使われるツールです。フォームを通して便利にユーザにサーバとデータをやり取りさせることができます。以前にWeb開発をしたことのあるユーザにとってはフォームはとてもお馴染みのものです。しかしC/C++のプログラマからすると少々取っ付きにくいかもしれません。フォームとは一体何でしょうか? フォームは表の要素を含むエリアです。フォームの要素はユーザがフォームの中で(例えば、テキストフィールド、コンボボックス、チェックボックス、セレクトボックス等です。)情報を入力する要素です。フォームはフォームタグ(\
-Goではformの処理にすでにとても簡単な方法が用意されています。Requestの中にformを専門に処理するものがあります。とても簡単にWeb開発に利用できるものです。4.1節の中でGoがどのようにフォームの入力を処理するかご説明します。いかなるユーザの入力も信用はできないので、これらの入力に対しバリデーションを行う必要があります。4.2節ではどのように普通のバリデーションを行うか、細かいデモンストレーションを行います。 +Goではformの処理に簡単な方法が既に用意されています。Requestの中にformを専門に処理するものがあり、簡単にWeb開発に利用できるます。4.1節の中でGoがどのようにフォームの入力を処理するかご説明します。いかなるユーザの入力も信用はできないので、これらの入力に対し検証を行う必要があります。4.2節では一般的にどのように検証を行うか、細かいデモンストレーションを行います。 -HTTPプロトコルはステートレスなプロトコルです。ではどのようにして一人のユーザを同定するのでしょうか?また、フォームが複数回送信されてしまわないように保証するにはどうするのでしょうか?4.3と4.4節ではcookie(cookieはクライアントに保存される情報です。handlerとサーバを通る度にやり取りされるデータです。)等をより詳しくご紹介します。 +HTTPプロトコルはステートレスなプロトコルです。ではどのようにして一人のユーザを同定するのでしょうか?また、フォームが複数回送信されてしまわないように保証するにはどうするのでしょうか?4.3と4.4節ではcookie(cookieはクライアントに保存される情報です。HTTP Headerを通してサーバーとやり取りされます)等をより詳しくご紹介します。 -フォームにはもうひとつ、ファイルをアップロードできるという大きな機能があります。Goはファイルのアップロードをどのように処理しているのでしょうか?大きなファイルをアップロードする際効率よく処理するにはどうすればよいでしょうか?4.5節ではGoによるファイルのアップロード処理の知識を一緒に勉強します。 +フォームにはもうひとつファイルをアップロードできるという大きな機能があります。Goはファイルのアップロードをどのように処理しているのでしょうか?大きなファイルをアップロードする際効率よく処理するにはどうすればよいでしょうか?4.5節ではGoによるファイルのアップロード処理の知識を一緒に勉強します。 ## 目次  diff --git a/ja/04.1.md b/ja/04.1.md index 53c62c83..a68f3fb3 100644 --- a/ja/04.1.md +++ b/ja/04.1.md @@ -1,6 +1,6 @@ # 4.1 フォームの入力を処理する -まずフォームによる送信の例を見てみましょう。以下のようなフォームの内容があるとします。login.gtplというファイルを新規作成します。(新しくディレクトリを作ってその中に入れてください) +まずフォームによる送信の例を見てみましょう。以下のようなフォームのコンテンツがあるとします。login.gtplというファイルを新規作成します。(新しくディレクトリを作ってその中に入れてください) @@ -15,9 +15,9 @@ -上で送信されるフォームはサーバの`/login`に渡ります。ユーザが情報を入力し、ログインをクリックした後、サーバのルーティングの`login`にリダイレクトします。まずはこの送信が何のメソッドによるものか判断する必要があります。POSTでしょうかGETでしょうか? +上で送信されるフォームはサーバの`/login`に渡されます。ユーザが情報を入力しログインをクリックした後、サーバのルーティングの`login`にリダイレクトします。まずはこの送信が何のメソッドによるものか判断する必要があります。POSTでしょうかGETでしょうか? -httpパッケージではとても簡単な方法で取得することができます。前のwebの例を基礎にloginページのformデータをどのように処理するか見てみましょう。 +httpパッケージにはそれを取得するとても簡単な方法があります。前のwebの例を基礎にloginページのformデータをどのように処理するか見てみましょう。 package main @@ -66,7 +66,7 @@ httpパッケージではとても簡単な方法で取得することができ } -上のコードにおいてリクエストを取得するメソッドは`r.Method`を通じて完了することがわかります。これは文字列型の変数です。GET, POST, PUT等のmethod情報を返します。 +上のコードにおいてリクエストのメソッドを取得するには`r.Method`だけで済むことがわかります。これは文字列型の変数です。GET, POST, PUT等のmethod情報を返します。 login関数では`r.Method`に従ってログイン画面を表示するのかログインロジックを処理するのかが判断されます。GETメソッドによるリクエストの場合はログイン画面を表示し、その他のメソッドによるリクエストではログインロジックを処理します。例えばデータベースを検索したり、ログイン情報を検証したりといった事です。 @@ -76,7 +76,7 @@ login関数では`r.Method`に従ってログイン画面を表示するのか 図4.1 ユーザログイン画面 -我々がユーザ名とパスワードを入力しても、サーバは何も出力しません。なぜでしょうか?デフォルトでは、Handlerの中ではformの内容を自動的に解析しないからです。必ず明示的に`r.ParseForm()`をコールした後でなければ、このフォームのデータに対して操作を行うことはできません。コードを少し修正して、`fmt.Println("username:", r.Form["username"])`の前に`r.ParseForm()`という一行を追加してください。再コンパイルしてもう一度入力、送信してみると、今度はサーバがあなたの入力したユーザ名とパスワードを出力するはずです。 +我々がユーザ名とパスワードを入力してもサーバは何も出力しません。なぜでしょうか?デフォルトではHandlerの中ではformの内容を自動的に解析しないからです。必ず明示的に`r.ParseForm()`をコールした後でなければ、このフォームのデータに対して操作を行うことはできません。コードを少し修正して、`fmt.Println("username:", r.Form["username"])`の前に`r.ParseForm()`という一行を追加してください。再コンパイルしてもう一度入力、送信してみると、今度はサーバがあなたの入力したユーザ名とパスワードを出力するはずです。 `r.Form`では全てのリクエストのデータが含まれています。例えばURLの中のquery-string、POSTのデータ、PUTのデータなどです。URLのquery-stringフィールドとPOSTが衝突する場合はsliceに保存されます。これには複数の値が保存されています。Goのオフィシャルドキュメントでは次のバージョンでPOST、GETといったデータは分離されると述べています。 diff --git a/ja/04.2.md b/ja/04.2.md index 6e22ee03..d5f1030c 100644 --- a/ja/04.2.md +++ b/ja/04.2.md @@ -1,20 +1,20 @@ # 4.2 フォームに入力された内容の検証 -Web開発の原則はユーザが入力したいかなる情報も信用してはならないということです。そのため、ユーザの入力した情報を検証しフィルターすることは非常に重要になってきます。ブログやニュースの中でどこそこのホームページがハッキングされたりセキュリティホールが存在するといったことをよく聞くかもしれません。これらの大部分はユーザの入力した情報に対してホームページが厳格な検証を行わなかった事によるものです。そのため、安全なWebプログラムを書くために、フォームの入力を検証する意義は非常に大きいのです。 +Web開発にはユーザが入力したいかなる情報も信用してはならないという原則があります。そのためユーザの入力した情報を検証しフィルターすることは非常に重要になってきます。ブログやニュースの中でどこそこのホームページがハッキングされたりセキュリティホールが存在するといったことをよく聞くかもしれません。これらの大部分はユーザの入力した情報に対してホームページが厳格な検証を行わなかった事によるものです。そのため、安全なWebプログラムを書くために、フォームの入力を検証する意義は非常に大きいのです。 -Webアプリケーションを書く時は主に2つの方面のデータ検証があります。ひとつはページ上でのjsによる検証で(現在この方面では多くのプラグインがあります。例えばValidationJSプラグインなどがそうです)、もうひとつはサーバ側での検証です。この節ではどのようにサーバでの検証を行うか解説します。 +Webアプリケーションを書く時は主に2つの場所でデータ検証を行います。ひとつはページ上でのJavaScriptによる検証で(現在この方面では多くのプラグインがあります。例えばValidationJSプラグインなどがそうです)、もうひとつはサーバ側での検証です。この節ではどのようにサーバでの検証を行うか解説します。 ## 必須フィールド -あるフォーム要素から一つの値を取り出したいとします。例えば、前の節のユーザ名はどのように処理するのでしょうか?Goにはbuiltin関数`len`があり、文字列の長さを得ることができます。lenを使ってデータの長さを測ることができます。例えば: +あるフォーム要素から一つの値を取り出したいとします。例えば前の節のユーザ名はどのように処理するのでしょうか?Goにはbuiltin関数`len`があり、文字列の長さを得ることができます。lenを使ってデータの長さを測ることができます。例えば: if len(r.Form["username"][0])==0{ //空だった場合の処理 } -`r.Form`は異なる型のフォーム要素の空白に対して異なる処理を行います。空のテキストフィールド、テキストエリアおよびファイルアップロードに対して、その要素の値を空にします。また選択されていないコンボボックスやセレクトボックスr.Formの中にはそもそもその項目を作りません。上の例の中の方法でデータを取得した時プログラムはエラーを発生させます。そのため、`r.Form.Get()`を使って値を取る必要があります。なぜなら、もしフィールドが存在しなかった場合、この方法で取得すると空の値を得るからです。ですが、`r.Form.Get()`は単体の値しか得ることができません。もしmapの値であれば、かならず上の方法で得る必要があります。 +`r.Form`は異なる型のフォーム要素の空白に対して異なる処理を行います。空のテキストフィールド、テキストエリアおよびファイルアップロードに対して、その要素の値を空にします。また選択されていないコンボボックスやセレクトボックスr.Formの中にはそもそもその項目を作りません。上の例の中の方法でデータを取得した時プログラムはエラーを発生させます。そのため、`r.Form.Get()`を使って値を取る必要があります。なぜなら、もしフィールドが存在しなかった場合、この方法で取得すると空の値を得るからです。ですが、`r.Form.Get()`は単体の値しか得ることができません。もしmapの値であれば必ず上の方法で得る必要があります。 ## 数 -たとえば、フォームからある人の年齢が50歳や10歳といった具体的な値を必要としていて、"おっさん"とか"若者"というようなものでなかったとします。このようにフォームの入力フィールドの中で数字のみを許容するようにさせたい場合、整数かどうかを判断するために、まずint型に変換を行ってから処理を行います。 +例えばフォームからある人の年齢が50歳や10歳といった具体的な値を必要としていて、"おっさん"とか"まだ若い"というようなものでなかったとします。このようにフォームの入力フィールドの中で数字のみを許容するようにさせたい場合、整数かどうかを判断するために、まずint型に変換を行ってから処理を行います。 正の整数を判断しようとする場合は、まずint型に変換してから処理を行います @@ -34,7 +34,7 @@ Webアプリケーションを書く時は主に2つの方面のデータ検 return false } -性能の高さを必要とするユーザからすれば、これはよく話題にのぼる問題です。彼らはなるべく正規表現を避けるべきだと考えています。なぜなら正規表現の速度は一般的に遅いからです。しかし現在のようにコンピュータの性能がこれほど発達した時代では、このように簡単な正規表現の効率と型変換関数の間ではそれほど大きな差はありません。もしあなたが正規表現に詳しく、他の言語でも使用されているのであれば、Goの中で正規表現を使うのは便利な方法の一つです。 +性能の高さを必要とするユーザからすればこれはよく話題にのぼる問題です。彼らはなるべく正規表現を避けるべきだと考えています。なぜなら正規表現の速度は一般的に遅いからです。しかし現在のようにコンピュータの性能がこれほど発達した時代では、このように簡単な正規表現の効率と型変換関数の間ではそれほど大きな差はありません。もしあなたが正規表現に詳しく、他の言語でも使用されているのであれば、Goの中で正規表現を使うのは便利な方法の一つです。 >Goの正規表現の実装は[RE2](http://code.google.com/p/re2/wiki/Syntax)です。すべての文字はUTF-8エンコーディングです。 @@ -95,7 +95,7 @@ selectには以下の要素があるとします: return false ## ラジオボタン -男と女という性別の選択肢を出力するようなラジオボタンで、どれかが選択されているか判断するとします。15歳の退屈な少年がhttpプロトコルの本を片手にtelnetクライアントからあなたのプログラムに対してリクエストを送信したとしましょう。あなたは男に1を、女に2を設定していて、彼が3という値を送信した場合、あなたのプログラムは例外を出すでしょうか?プルダウンメニューの判断と同じように我々が得ようとしている値がそもそも設定されたものであるかを判断しなければなりません。 +男と女という性別の選択肢を出力するようなラジオボタンでどれかが選択されているか判断するとします。15歳の退屈な少年がhttpプロトコルの本を片手にtelnetクライアントからあなたのプログラムに対してリクエストを送信したとしましょう。あなたは男に1を、女に2を設定していて、彼が3という値を送信した場合、あなたのプログラムは例外を出すでしょうか?プルダウンメニューの判断と同じように我々が得ようとしている値がそもそも設定されたものであるかを判断しなければなりません。 男 女 @@ -131,8 +131,7 @@ selectには以下の要素があるとします: 上の`Slice_diff`という関数には私のオープンソースのライブラリが含まれます(sliceとmapを操作するライブラリ)[https://github.com/astaxie/beeku](https://github.com/astaxie/beeku) ## 日付と時間 -ユーザが入力した日時が有効か確認したいとします。例えば -、ユーザがスケジュールで8月45日にパーティを開く予定を入力したり、未来の時間を誕生日にしてみたりといった場合です。 +ユーザが入力した日時が有効か確認したいとします。例えばユーザがスケジュールで8月45日にパーティを開く予定を入力したり、未来の時間を誕生日にしてみたりといった場合です。 Goではtimeの処理パッケージを提供しています。ユーザの入力した年月日を目的の時間に変換してから、判断を行います。 @@ -142,7 +141,7 @@ Goではtimeの処理パッケージを提供しています。ユーザの入 timeを取得した後、多くの時間関数の操作を行うことができます。具体的な判断は自身の要件に合わせて調整してください。 ## 身分証明書番号 -フォームに入力された身分証を検証する場合、正規表現を使っても簡単に検証できます。しかし身分証明書番号は15桁と18桁があるので2つとも検証しなければなりません。(訳注:中国では身分証明書とともに個人を特定する国民背番号があります。) +フォームに入力された身分証明書を検証する場合、正規表現を使って簡単に検証できます。しかし身分証明書番号は15桁と18桁があるので2つとも検証しなければなりません。(訳注:中国では身分証明書に個人を特定する身分証明番号(以前は15桁、現在は18桁)が記載されています。) //15桁の身分証明書の検証。15桁はすべて数字です。 if m, _ := regexp.MatchString(`^(\d{15})$`, r.Form.Get("usercard")); !m { @@ -154,7 +153,7 @@ timeを取得した後、多くの時間関数の操作を行うことができ return false } -以上よく使用されるサーバ側でのフォーム要素の検証をいくつかご紹介しました。このイントロダクションを通してGoによるデータ検証、特に正規表現での処理に対する理解が深まるよう願っています。 +以上、よく使用されるサーバ側でのフォーム要素の検証をいくつかご紹介しました。このイントロダクションを通してGoによるデータ検証、特に正規表現での処理に対する理解が深まるよう願っています。 ## links * [目次](