⛅
Cloudflare Workers で Form の結果を表示する
はじめに
ここでは、Formで送信した結果に対して処理を行い、結果を表示することを行う。
りんごの購入数とみかんの購入数を入力し、購入するボタンをクリックすると、結果が表示される。
リクエスト送信前
リクエスト送信後
1. プロジェクトを作成する
- サインアップする。
- プロジェクトを作成する。
- プロジェクト名: my-app
- TypeScriptを選択
npm create cloudflare@latest -- my-app
What type of application do you want to create?
> "Hello World" Worker
Do you want to use TypeScript?
> Yes
Do you want to use git for version control?
> No
Do you want to deploy your application?
> Yes
- デプロイが完了後、
deployment is ready at:
の後に URL が表示され、ブラウザが開く。
- ログイン後、左タブのWorkers & Pagesで確認できる。
2. フォームの作成
ここでは、Node.jsで簡易的なフォーム画面を作成する。
リクエストを送信に関しては、次のステップ3を参考にする。
- プロジェクトのディレクトリ作成
mkdir my-app-front
cd my-app-front
-
package.json
ファイルの初期化
npm init
- ファイルの作成
JSファイルのurl
には、1で生成されたURLを記入する。
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>My Project</title>
<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>
<main>
<form id="form">
<div>
<label>りんご(200円): </label>
<input type="number" name="apple" id="apple" />
</div>
<div>
<label>みかん(300円): </label>
<input type="number" name="orange" id="orange" />
</div>
<input type="submit" value="購入する" />
</form>
<ul id="form-result">
<p>注文結果:</p>
<p>注文番号:</p>
<p id="order-number"></p>
<p>合計金額:</p>
<li id="total-amount"></li>
</ul>
</main>
<script src="app.js"></script>
</body>
</html>
style.css
* {
margin: 0;
padding: 0;
}
main {
padding: 100px 0 0 100px;
}
form {
margin-bottom: 40px;
}
ul {
list-style: none;
padding-left: 0;
}
app.js
document.getElementById("form").addEventListener("submit", function (e) {
e.preventDefault();
const formData = new FormData(e.target);
const url = 1で生成されたURL;
fetch(url, {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(Object.fromEntries(formData.entries())),
})
.then((response) => response.json())
.then((data) => {
const orderNumber = document.getElementById("order-number");
const totalAmount = document.getElementById("total-amount");
orderNumber.textContent = data["order-number"];
totalAmount.textContent = data["total-amount"] + "円";
})
.catch((error) => {
console.error("リクエストエラー", error);
});
});
- ローカルサーバーの起動
ここでは、http-server
をインストールして起動する。
ブラウザで http://localhost:8080 にアクセスすると、作成したページを確認できる。
npm install -g http-server
http-server
3. 処理を変更してリデプロイ
ここでは、リクエストを受け取った後、合計金額を計算&注文番号を生成する処理を行い、レスポンスを返す。コードは、1で作成したmy-app
ディレクトリ内のsrc/index.ts
を編集する。
データ設定(リクエスト)
JSON Key | 型 | 必須 | 値の説明 |
---|---|---|---|
apple | Int | ○ | りんごの購入数 |
orange | Int | ○ | みかんの購入数 |
データ設定(レスポンス)
JSON Key | 型 | 必須 | 値の説明 |
---|---|---|---|
order-number | Int | ○ | 注文番号。RANDOM_MIN からRANDOM_MAX の間のランダムな整数 |
total-amount | Int | ○ |
APPLE_AMOUT とORANGE_AMOUT をもとにした合計金額 |
...
interface FormData {
apple: number;
orange: number;
}
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
try {
if (request.method === 'POST') {
const APPLE_AMOUT = 200;
const ORANGE_AMOUT = 300;
const RANDOM_MAX = 10000;
const RANDOM_MIN = 1;
const formData: FormData = await request.json();
const orderNumber = Math.floor(Math.random() * (RANDOM_MAX + 1 - RANDOM_MIN)) + RANDOM_MIN;
const totalAmount = formData['apple'] * APPLE_AMOUT + formData['orange'] * ORANGE_AMOUT;
const responseData = {
'order-number': orderNumber,
'total-amount': totalAmount,
};
const response = new Response(JSON.stringify(responseData));
response.headers.set('Content-Type', 'application/json');
response.headers.set('Access-Control-Allow-Origin', '*');
response.headers.set('Access-Control-Allow-Headers', 'X-Requested-With, Origin, X-Csrftoken, Content-Type, Accept');
return response;
} else if (
// プリフライトリクエストに対してOKステータスを返す
request.method === 'OPTIONS'
) {
return new Response(null, {
status: 200,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type',
},
});
} else {
return new Response('Method Not Allowed', {
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'X-Requested-With, Origin, X-Csrftoken, Content-Type, Accept',
},
status: 405,
statusText: 'Method Not Allowed',
});
}
} catch (error) {
console.error('Error processing form data:', error);
return new Response('Internal Server Error', {
status: 500,
statusText: 'Internal Server Error',
});
}
},
};
編集後、以下のコマンドでデプロイする。
npx wrangler deploy
参考
Discussion