• Koa 提交和接收 JSON 表单数据


    来自 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

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

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

    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

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

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

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

    - <form action="/save" method="POST">
    + <form action="/save" method="POST" onsubmit="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;
                }
            }
    
        <span class="pl-en">fetch</span>(<span class="pl-s"><span class="pl-pds">"</span>/save<span class="pl-pds">"</span></span>, {
            method<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span>POST<span class="pl-pds">"</span></span>,
            headers<span class="pl-k">:</span> {
            <span class="pl-s"><span class="pl-pds">"</span>Content-Type<span class="pl-pds">"</span></span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span>application/json<span class="pl-pds">"</span></span>
            },
            body<span class="pl-k">:</span> <span class="pl-c1">JSON</span>.<span class="pl-c1">stringify</span>(data)
        })
            .<span class="pl-c1">then</span>(<span class="pl-k">function</span>(<span class="pl-smi">response</span>) {
            <span class="pl-k">return</span> <span class="pl-smi">response</span>.<span class="pl-en">json</span>();
            })
            .<span class="pl-c1">then</span>(<span class="pl-k">function</span>(<span class="pl-smi">response</span>) {
            <span class="pl-en">console</span>.<span class="pl-c1">log</span>(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 格式的表单数据

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

  • 相关阅读:
    ASP.NET 学习日志
    igoogle 小工具
    nios ann 语音识别
    ASP 3.5 读书笔记
    C# delegate and event 续
    paper
    网站白痴的 ASP.NET website 学习日志
    盒子模型
    将对象序列化成json
    不错的Oracle 存储过程例子
  • 原文地址:https://www.cnblogs.com/Wayou/p/koa_json_form_data.html
Copyright © 2020-2023  润新知