[DAY29]番外篇-使用fetch传送表单资料

昨天我们介绍fetch用get方式来请求资料,并将取得的资料转为JSON格式做运用,今天要来介绍fetch的post方法,用非同步的方式来传送表单资料。以下开始进入主题:

准备表单UI

沿用前天弹出表单视窗的范例,为了可以让程序码变得更简短,这里仅保留表单直接放入render,并去除弹跳视窗功能模组(Modal):

src/pages/Contact.js

//引入外框组件
import { App } from './App'
 
export const Contact = {
    render: () => {
        const content = `
          <div class="container">
            <h1>填写表单</h1>
            <h6>请填写下方表单</h6>
              <form>
                <div class="form-group">
                  <label for="name">称呼</label>
                  <input type="text" class="form-control" name="name" placeholder="请填写您的称呼" required>
                </div>
                <div class="form-group">
                  <label for="email">Email</label>
                  <input type="email" class="form-control" name="email" placeholder="请填写email" required>
                </div>
                <div class="form-group">
                  <label for="message">留言内容</label>
                  <textarea type="email" class="form-control" name="message" placeholder="请填写内容" required></textarea>
                </div>
                <div class="form-group">
                  <button type="submit" class="btn btn-primary" id="submit">提交</button>
                </div>
              </form>
          </div>
        `
 
        return App.render(content)
    },
}

表单里我们放置三个输入框,依序是name、email及message,为了等等传送表单资料(formData),将每个输入框给予name属性,最後再放置一个送出的submit button。

fetch传送表单

我们先看看下面的例子,这是所熟知最传统的方式,使用html的form来传送,要传送表单资料除了设定method为POST,enctype也要设定为multipart/form-data。

<form action="https://test.com/post" method="POST" enctype="multipart/form-data">

不过这样的方式会造成请求资源的同时做转址,转向至action设定的 「https://test.com/post」 ,为了不让浏览器产生转址,我们可以使用javascript建立表单物件,搭配使用非同步的方式来传送资料。直接来看fetch POST如何运行:

src/pages/Contact.js

export const Contact = {
    listener: {
        click: function (e) {
            if (
                e.target.closest('button') &&
                e.target.closest('button').id === 'submit'
            ) {
                //取消预设submit事件
                e.preventDefault()
 
                // 建立formData物件
                const fd = new FormData(document.querySelector('form'))
 
                // fetch post
                fetch('test.com/post', {
                    method: 'POST',
                    body: fd,
                    headers: { 'Content-Type': 'multipart/form-data' },
                })
                .then((res) => res.json())
                .then((data) => {
                    console.log(data)
                })
            }
        },
    },
    render: () => {

这边新增listener属性来增加click监听事件,需要注意的是当按下submit按钮时,要用preventDefault()取消预设submit事件,否则会转址。建立表单物件起手式,宣告并建立FormData表单物件,可以带入现有的表单做传送,或是建立後使用append来增加表单资料,参阅MDN上面的说明:

FormData 介面可为表单资料中的栏位/值建立相对应的的键/值对(key/value)集合,之後便可使用 XMLHttpRequest.send() 方法来送出资料。它在编码类型设定为 multipart/form-data 时会采用与表单相同的格式送出。

在fetch的第一个参数放入URI,因为手边没有API,所以先随意打,这边只要了解body夹带的资料内容。比较重要的是第二个参数设定如下:

{
    method: 'POST',
    body: fd,
    headers: { 'Content-Type': 'multipart/form-data' },
}
  • method:表示设置传输方式为POST
  • body:要传输的讯息,这里放置我们刚刚建立的表单物件,若传输JSON格式资料记得用JSON.stringify转为字串
  • headers:HTTP传输的内容类型, multipart/form-data表示传送表单物件,若传输JSON格式资料可以改为application/json

测试结果

填完资料後按下送出,用Chrome Devtools到Network看看body传送的资讯:

可以看到框框处是formData里面传送的资料,其中key对应form表单的name,value对应为填入表单的值。以上就是使用fetch post来传输资料,以上实做到这里算是结束了,准备迎接完赛日的到来吧:)


<<:  Nice day 28 (iphone10s 功能挖掘)-常用资料选择器

>>:  Day 28 -- Rails 实作 Ransack 简易搜寻及排序功能

Day15 - Ptt换页及新增文章列表项目

今天的内容算是当初一时没考虑到的东西。 主要是Ptt一页的文章最多列出20篇,若要搜寻到20篇以前的...

从零开始学游戏开发:建立得分条 Part1.开始

这是 Roblox 从零开始系列,使用者介面章节的第一个单元,你将开始学习如何设计出一个精美的得分条...

Day26. Blue Prism取号一把罩–BP自动取得订单编号

一般订购的程序都是由下订单开始, 接着取单号为依据来分批或批次采购相关物资, 因此订单编号有举足轻重...

Day12 分散式储存系统的必要功能

储存领域有个重要的定理 - CAP定理,C(Consistency一致性)A(Availabilit...

Day 12: 前往未知秘境!在iOS上展示Ktor资料!

Keyword: swift,swiftUI,ObservableObject 到Day12 使用s...