Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GET/POST リクエストの書き直し #835

Merged
merged 24 commits into from
Sep 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 24 additions & 28 deletions docs/3-web-servers/07-get-post/index.mdx
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
---
title: GETリクエストとPOSTリクエスト
title: HTTPリクエストメソッド
---

import postInDevelopment1 from "./postInDevelopment1.mp4";
import postInDevelopment2 from "./postInDevelopment2.mp4";
import postInDevelopment3 from "./postInDevelopment3.mp4";
import networkDevtool1 from "./network-devtool-1.mp4";
import networkDevtool2 from "./network-devtool-2.mp4";

## GETリクエストとPOSTリクエスト
## リクエストの種類

HTTP上の通信において<Term>クライアント</Term>から<Term>サーバー</Term>への要求を<Term>リクエスト</Term>と言いましたが、今まで扱ってきたのはその中でも**GETリクエスト**と呼ばれるものになります。
{/* prettier-ignore */}
<Term>クライアント</Term>から<Term>サーバー</Term>への要求を<Term>リクエスト</Term>と言いました。HTTPのリクエストには、<Term type="httpMethod">**メソッド**</Term>と呼ばれる区分があります。

GETリクエストで<Term>サーバー</Term>にデータを送信する場合、前頁で扱ったように、<Term>クエリパラメータ</Term>としてURLの末尾に付加するしかありませんが、この方式だと困ってしまうことがあります。例えばパスワードなどを入力したときにURLにパスワード情報が載ってしまい機密情報の漏洩につながります。また、URLの長さの制限のため、大量の情報は送信できません
今まで扱ってきたのはその中でもメソッドがGETである、**GETリクエスト**と呼ばれるものになります

そこで用いるのが**POSTリクエスト**です。POSTリクエストでは、<Term>クエリパラメータ</Term>とは別に、<Term>リクエストボディ</Term>と呼ばれる領域を使って大容量のデータを送信できます
GETリクエストで<Term>サーバー</Term>にデータを送信する場合、前頁で扱ったように、<Term>クエリパラメータ</Term>としてURLの末尾に付加するしかありませんが、この方式だと困ってしまうことがあります。例えばパスワードなどを入力したときにURLにパスワード情報が載ってしまい機密情報の漏洩につながります。また、URLの長さの制限のため、大量の情報は送信できません

HTTPリクエストのこのような区分を、<Term>**HTTPメソッド**</Term>と呼びます
そこで用いるのが<Term type="httpMethod">メソッド</Term>がPOSTであるHTTPリクエストの、**POSTリクエスト**です。POSTリクエストでは、<Term>クエリパラメータ</Term>とは別に、<Term>リクエストボディ</Term>と呼ばれる領域を使って大容量のデータを送信できます

![HTTPメソッドの比較](./method-comparison.png)

前頁の例を、POSTリクエストを用いて書き直してみましょう。`form`要素の`method`属性に`post`を指定することで、ブラウザは送信ボタンが押されたときに`POST`メソッドの<Term>リクエスト</Term>を発行します
前頁の例を、POSTリクエストを用いて書き直してみましょう。`form`要素の`method`属性に`post`を指定することで、ブラウザは送信ボタンが押されたときにPOSTリクエストを発行します

```html title="public/index.html"
<!doctype html>
Expand Down Expand Up @@ -55,43 +55,39 @@ app.listen(3000);

<ViewSource url={import.meta.url} path="_samples/post-request" />

これまで利用していた`app.get` ([`express.Application#get`メソッド](https://expressjs.com/ja/api.html#app.get.method)) では、GETメソッドの<Term>リクエスト</Term>しか受け付けられないため、`/send`へのPOSTリクエストを受け付けるために`app.post` ([`express.Application#post`メソッド](https://expressjs.com/ja/api.html#app.post.method)) を利用しています。
これまで利用していたExpressの[`get`メソッド](https://expressjs.com/ja/api.html#app.get.method)では、GETリクエストしか受け付けられないため、`/send`へのPOSTリクエストを受け付けるために[`post`メソッド](https://expressjs.com/ja/api.html#app.post.method)を利用しています。

{/* prettier-ignore */}
<Term>クエリパラメータ</Term>にアクセスするには、`request.query` (<a href="https://expressjs.com/ja/api.html#req.query">`express.Request#query`プロパティ</a>)を使用しましたが、<Term>リクエストボディ</Term>を使用するには、`request.body` (<a href="https://expressjs.com/ja/api.html#req.body">`express.Request#body`プロパティ</a>)を使用します
<Term>クエリパラメータ</Term>には、`request`オブジェクトの<a href="https://expressjs.com/ja/api.html#req.query">`query`プロパティ</a>からアクセスできましたが、<Term>リクエストボディ</Term>には、`request`オブジェクトの<a href="https://expressjs.com/ja/api.html#req.body">`body`プロパティ</a>からアクセスできます

`app.use(express.urlencoded({ extended: true }));`は、<Term>リクエストボディ</Term>の解釈方法を定めています。HTMLのフォームが送信されたとき、ブラウザが発行するPOSTリクエストの<Term>リクエストボディ</Term>は、<Term>クエリパラメータ</Term>と同じくURLエンコードされた形式で記述されます。[`express.urlencoded`関数](https://expressjs.com/ja/api.html#express.urlencoded)は、URLエンコードされた<Term>リクエストボディ</Term>を読み取り、`request.body`にオブジェクトの形式でデータを保存する役割を担っています。

このシステムでは、まず次のような画面が表示されます。

![名前と年齢を入力1](postRequest1.png)
このWebサイトにアクセスし、以下のように入力します。

以下のように入力して、送信ボタンをクリックすると
![名前と年齢を入力し、これから送信する。](post-request.png)

![名前と年齢を入力2](postRequest2.png)
送信ボタンをクリックすると`http://localhost:3000/send`に移り、以下のような画面が表示されます。GETリクエストの時と違い、<Term>クエリパラメータ</Term>がURLに表示されていないことが分かります。

`http://localhost:3000/send`に移り、以下のような画面が表示されます。GETリクエストの時と違い、<Term>クエリパラメータ</Term>がURLに表示されていないことが分かります。
![送信後、URLにクエリパラメータが表示されていない。](post-request-2.png)

![名前と年齢を入力3](postRequest3.png)
![GETリクエストとPOSTリクエスト](requestAndResponse.png)

## POSTリクエストを開発者ツールで覗いてみる
## ブラウザの通信を覗いてみる

実際にPOSTリクエストの中身がどうなっているか覗いてみましょう。まず開発者ツールの`Network`タブを開き、文字を入力して送信してみます
ブラウザの開発者ツールには、ブラウザの行うネットワーク通信を監視するツールが搭載されています。これを使い、実際にPOSTリクエストの中身がどうなっているか覗いてみましょう

<video src={postInDevelopment1} controls />
開発者ツールの`Network`タブを開き、フォームに文字を入力して送信してみます。

そして`Name`欄の`send`をクリックし、`Headers`を選択すると`general`欄の`Requested method`が`POST`になっています。また、`Headers`の横にある`Payload`を選択し`Form data`を見ると、`name`と`age`の情報が載っています
そして`Name`欄の`send`をクリックし、`Headers`を選択すると`Request Method`が`POST`になっています。

<video src={postInDevelopment2} controls />
<video src={networkDevtool1} controls />

ここからさらに、`Form data`の横の`view source`や`view URL-encoded`も見てみましょう。するとURLエンコードされた<Term>リクエストボディ</Term>の中身を見ることができます。
また、`Headers`の横にある`Payload`を選択し`Form Data`を見ると、`name`と`age`の情報が載っています。さらに、`Form Data`の横の`view source`や`view URL-encoded`も見てみましょう。するとURLエンコードされた<Term>リクエストボディ</Term>の中身を見ることができます。

<video src={postInDevelopment3} controls />
<video src={networkDevtool2} controls />

以上のようにして、POSTリクエストの中身を覗くことができます。

![GETリクエストとPOSTリクエスト](requestAndResponse.png)

## 演習問題

古き良き掲示板システムを作ってみましょう。次のようなページを作成してください。
Expand Down
Binary file not shown.
Binary file not shown.
Binary file added docs/3-web-servers/07-get-post/post-request-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/3-web-servers/07-get-post/post-request.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed docs/3-web-servers/07-get-post/postRequest1.png
Binary file not shown.
Binary file removed docs/3-web-servers/07-get-post/postRequest2.png
Binary file not shown.
Binary file removed docs/3-web-servers/07-get-post/postRequest3.png
Binary file not shown.
2 changes: 1 addition & 1 deletion src/components/Term/definitions.js
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ export default {
httpMethod: {
name: "HTTPメソッド",
definition:
"HTTPリクエストの種類。GETやPOSTなどがある。GETリクエストにはリクエストボディが存在しないが、POSTリクエストでは利用できる。",
"HTTPリクエストの種類。GETやPOSTなどがある。GETリクエストではリクエストボディを利用できないが、POSTリクエストでは利用できるなどの違いがある。",
referencePage: "/docs/web-servers/get-post/",
},
npxCommand: {
Expand Down
1 change: 0 additions & 1 deletion src/components/Term/type-map.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ const typeMap = new Map([
["リクエストヘッダ", "httpHeaderBody"],
["リクエストボディ", "httpHeaderBody"],
["レスポンスボディ", "httpHeaderBody"],
["HTTPメソッド", "httpMethod"],
["GETリクエスト", "httpMethod"],
["POSTリクエスト", "httpMethod"],
["npxコマンド", "npxCommand"],
Expand Down