Koa 提交和接收 JSON 表单数据

it2022-05-07  1

来自 url 中的 query 参数可直接通过 context.query 获取,但 POST 方式提交的表单数据则需要借助中间件的解析来完成,比如 koa-bodyparser。

首先准备好一个表单页面,为了演示,其中包含一个数组类型的数据。

index.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>post json</title> </head> <body> <form action="/save" method="POST"> <div> <label for="name" >name: <input type="text" name="name" id="name" value="Tom" /> </label> </div> <div> <label for="age" >age: <input type="number" name="age" id="age" value="19" /> </label> </div> <div> <label >hobbies: <br /> <input type="text" name="hobbies[0]" id="hobbies[0]" value="reading" /> <br /> <input type="text" name="hobbies[1]" id="hobbies[1]" value="music" /> <br /> <input type="text" name="hobbies[2]" id="hobbies[2]" value="swim" /> </label> </div> <button type="submit">Submit</button> </form> </body> </html>

server.js

var Koa = require("koa"); var Router = require("koa-router"); var fs = require("fs"); var bodyParser = require("koa-bodyparser"); var app = new Koa(); var router = new Router(); app.use(bodyParser()); router.get("/", async (ctx, next) => { ctx.type = "html"; ctx.body = fs.createReadStream("index.html"); }); router.post("/save", async (ctx, next) => { ctx.body = ctx.request.body; }); app.use(router.routes()).use(router.allowedMethods()); app.listen(3000); console.log("server started at http:localhost:3000");

通过 Node.js 调试模式启动服务可查看到接收到的数据,其中数据类型解析正常。

$ node --inspect-brk server.js server started

接收到的表单数据

但其实前台页面提交的并不是 JSON 类型,这是 koa-bodyparse 解析后的结果。通过 Chrome Devtools 的网络面板可看到,真实的类型为 Request 中 Content-Type 字段,为 application/x-www-form-urlencoded。

表单提交时的请求类型为 `application/x-www-form-urlencoded`

原生的 HTML 表单 <form> 是没有 JSON 类型的,其总共有三种默认的格式,

application/x-www-form-urlencodedmultipart/form-datatext/plain

默认为 application/x-www-form-urlencoded,可通过 <form> 表单的 enctype 指定。

所以真正意义上以 JSON 格式提交,需要借助 JavaScript,真实场景下表单也大多会走代码提交而非原生 submit 类型的 <button>。

首页更新表单代码添加 onsubmit 方法:

- <form action="/save" method="POST"> + <form action="/save" method="POST" οnsubmit="submitForm(event)" id="myForm">

添加以下代码到页面以提交表单:

<script> function submitForm(event) { event.preventDefault(); var formData = new FormData(myForm); let data = {}; for (var [key, value] of formData.entries()) { if (key.startsWith("hobbies")) { data["hobbies"] ? data["hobbies"].push(value) : (data["hobbies"] = [value]); } else { data[key] = value; } } fetch("/save", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }) .then(function(response) { return response.json(); }) .then(function(response) { console.log(response); }); } </script>

最后完整的后台与页面代码为:

server.js var Koa = require("koa"); var Router = require("koa-router"); var fs = require("fs"); var bodyParser = require("koa-bodyparser"); var app = new Koa(); var router = new Router(); app.use(bodyParser()); router.get("/", async (ctx, next) => { ctx.type = "html"; ctx.body = fs.createReadStream("index.html"); }); router.post("/save", async (ctx, next) => { ctx.body = ctx.request.body; }); app.use(router.routes()).use(router.allowedMethods()); app.listen(3000); console.log("server started at http:localhost:3000"); index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>post json</title> </head> <body> <form action="/save" method="POST" onsubmit="submitForm(event)" id="myForm"> <div> <label for="name" >name: <input type="text" name="name" id="name" value="Tom" /> </label> </div> <div> <label for="age" >age: <input type="number" name="age" id="age" value="19" /> </label> </div> <div> <label >hobbies: <br /> <input type="text" name="hobbies[0]" id="hobbies[0]" value="reading" /> <br /> <input type="text" name="hobbies[1]" id="hobbies[1]" value="music" /> <br /> <input type="text" name="hobbies[2]" id="hobbies[2]" value="swim" /> </label> </div> <button type="submit">Submit</button> </form> <script> function submitForm(event) { event.preventDefault(); var formData = new FormData(myForm); let data = {}; for (var [key, value] of formData.entries()) { if (key.startsWith("hobbies")) { data["hobbies"] ? data["hobbies"].push(value) : (data["hobbies"] = [value]); } else { data[key] = value; } } fetch("/save", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }) .then(function(response) { return response.json(); }) .then(function(response) { console.log(response); }); } </script> </body> </html>

再次查看提交时的 Content-Type 及所提交的数据,已经是 JSON 格式了。

通过 fetch 提交 JSON 格式的表单数据

转载于:https://www.cnblogs.com/Wayou/p/koa_json_form_data.html


最新回复(0)