メインコンテンツまでスキップ

フォーム

クエリパラメータの利用

入力した内容によって、次に移る(表示される)ページが異なるウェブページがあります。例として、Google で utcode と検索した際に表示される検索結果のページを考えてみましょう。

クエリパラメータ

このページの URL は、次のようになっています。

https://www.google.com/search?q=utcode&sourceid=chrome&ie=UTF-8

このようなページでは、入力した内容によって異なるウェブページが表示されるよう、入力した内容が移った先のページの URL に反映されています。この例では、URL の末尾に ?q=utcode&sourceid=chrome&ie=UTF-8 というデータが付加されています。これがクエリパラメータです。

クエリパラメータは、キーと値の組み合わせにより表現されます。先ほどの Google の検索結果であれば、次のような 3 つのパラメータが存在することになります。

キー
qutcode
sourceidchrome
ieUTF-8

Express からクエリパラメータを利用する場合、request.query (express.Request#query プロパティ) にこれらの値が格納されています。

main.mjs
import express from "express";

const app = express();
app.get("/", (request, response) => {
response.send(JSON.stringify(request.query));
});
app.listen(3000);
JSON とは何か

JSON は「JavaScript Object Notation」の略で JavaScript のオブジェクト表記法を倣ったデータ記述方法のことです。つまりデータの保存はオブジェクトの形式で行うという決まり事です。表記法の名前なので臆する必要はありません。

JSON.stringify メソッド

JSON.stringify メソッドはオブジェクトを JSON 形式の文字列に変換するメソッドです。

URL として使用できない文字の対処方法

URL として使用できない文字(日本語文字など)はURL エンコードする必要があります。JavaScript なら encodeURIComponent 関数で変換できます。

encodeURIComponent("日本語"); // "%E6%97%A5%E6%9C%AC%E8%AA%9E"

サーバーにデータを送信する

form 要素を使うとユーザーの入力からクエリパラメータを生成してページ遷移できます。

  • formaction 属性: フォーム送信時に移動し、データを送信するページ
  • input 要素: テキストボックス
  • inputname 属性: クエリパラメータのキー
  • button 要素: form 内のボタンをクリックすると formaction に指定したページに遷移します(送信ボタンになります)

以下のコードの、HTML ファイルと、JavaScript ファイルを作成して実行してみましょう。

static/index.html
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<title>フォーム</title>
</head>
<body>
<form action="/send">
<input name="name" />
<input name="age" />
<button>送信</button>
</form>
</body>
</html>
main.mjs
import express from "express";

const app = express();
app.use(express.static("static"));
app.get("/send", (request, response) => {
response.send(
`あなたの名前は${request.query.name}で、${request.query.age}歳ですね。`,
);
});
app.listen(3000);

上記コードを実行すると、以下のような画面がブラウザに表示されます。

初めの画面

以下のように入力して、送信ボタンをクリックすると、 初めの画面に入力

http://localhost:3000/send に移り、以下のような画面が表示されます。

http://localhost:3000/send

このページの URL を見てみましょう。特に、クエリパラメータの部分に注目してみましょう。 URLのクエリパラメータ

初級課題

ログイン画面を作ってみましょう。以下のような画面を作成してください。

ログイン画面

ユーザー名とパスワードを入力して、ログインボタンを押すと、/login に移動し、ログインに成功した場合は ログインに成功しました。 と表示し、失敗した場合は ログインに失敗しました。 と表示するようにしてください。(POSTリクエストを使ってみましょう。)

ヒント

ユーザー名とパスワードは以下のように配列で管理してみましょう。

const userCredentials = [
{ username: "tanaka", password: "kfae12F@" },
{ username: "sato", password: "faewbnpE3b=" },
{ username: "endo", password: "fEnEoB131b" },
];

Array#find メソッドを使用して、ユーザー名とパスワードが一致する要素を探してみましょう。

解答例: ログイン画面
static/index.html
<form action="/login" method="post">
<input type="text" name="username" placeholder="ユーザー名" />
<input type="password" name="password" placeholder="パスワード" />
<button>ログイン</button>
</form>
main.mjs
import express from "express";
const app = express();

app.use(express.static("static"));
app.use(express.urlencoded({ extended: true }));

const userCredentials = [
{ username: "tanaka", password: "kfae12F@" },
{ username: "sato", password: "faewbnpE3b=" },
{ username: "endo", password: "fEnEoB131b" },
];

app.post("/login", (request, response) => {
const username = request.body.username;
const password = request.body.password;

const userCredential = userCredentials.find(
(userCredential) =>
userCredential.username === username &&
userCredential.password === password,
);
if (userCredential === undefined) {
response.send("ログインに失敗しました。");
} else {
response.send("ログインに成功しました。");
}
});

app.listen(3000);

中級課題

書籍検索システムを作ってみましょう。まずは、配列に本のデータを登録します。

const books = [
{ title: "吾輩は猫である", author: "夏目漱石" },
{ title: "こころ", author: "夏目漱石" },
{ title: "坊つちやん", author: "夏目漱石" },
{ title: "舞姫", author: "森鴎外" },
{ title: "高瀬舟", author: "森鴎外" },
];

著者名を入力して送信すると、その著者の出版物が一覧表示されるシステムを作ってみましょう。

Array#filter メソッド

Array#filter メソッドは、関数オブジェクトを引数としてとり、その関数が true となる要素だけからなる新しい配列を返すメソッドです。

const numbers = [1, 2, 3, 4, 5, 6, 7, 8];

/// [2, 4, 6, 8]
const evenNumbers = numbers.filter((number) => number % 2 === 0);
解答例
static/index.html
<form action="/send">
<input name="author" />
<button>送信</button>
</form>
main.mjs
import express from "express";
import { readFileSync } from "node:fs";

const app = express();

const books = [
{ title: "吾輩は猫である", author: "夏目漱石" },
{ title: "こころ", author: "夏目漱石" },
{ title: "坊つちやん", author: "夏目漱石" },
{ title: "舞姫", author: "森鴎外" },
{ title: "高瀬舟", author: "森鴎外" },
];

app.use(express.static("static"));

app.get("/send", (request, response) => {
const selectedBooks = books.filter(
(book) => book.author === request.query.author,
);
const template = readFileSync("./send.html", "utf-8");
const html = template.replace(
"<!-- books -->",
selectedBooks.map((book) => `<li>${book.title}</li>`).join(""),
);
response.send(html);
});

app.listen(3000);