ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

The JavaScript Way 第 23 章实战:用 `fetch()` 向 Web 服务器发送数据(FormData 与 JSON 双路径)

The JavaScript Way 第 23 章实战:用 `fetch()` 向 Web 服务器发送数据(FormData 与 JSON 双路径) 教程文档【免费下载链接】thejswayThe JavaScript Way book项目地址https://gitcode.com/gh_mirrors/th/thejsway点击查看免费下载本篇文章基于开源书籍The JavaScript Way仓库源码第 23 章「Send data to a web server」展开。前几章解决了如何从服务器读取数据第 21 章的fetch()基础、第 22 章的 Web API 消费本章则聚焦反向操作——如何把数据发给服务器。读完本文你将掌握用FormData对象发送 HTML 表单数据与自定义键值对、用JSON.stringify()发送结构化 JSON 数据、理解fetch()第二个参数method / headers / body的完整语义并能独立完成章节末尾的「New article」与「Visited countries」两个实战练习。发送数据的基础POST 方法与请求体向服务器发送数据的标准姿势是发起一个HTTPPOST请求并把待发送的数据放进**请求体request body**中。回顾 第 20 章 对 HTTP 协议的讲解HTTP 请求的第一行包含请求方法method / command主流方法中GET用于访问资源而POST正是把信息推送给服务器的专用方法。这也解释了为什么本章所有示例都围绕POST展开——例如练习中的服务器 URL 明确声明只接受POST请求。请求体的数据格式取决于服务器端的预期通常有两种数据形态适用场景对应 JavaScript API键值对key/value pairs表单直接提交、简单字段FormData对象JSON结构化数据嵌套字段、数组、复杂类型JSON.stringify() 请求头声明选择依据很简单服务器要什么就发什么。接下来分别走通这两条路。发送表单数据FormData对象如果服务器期望的是直接的表单字段即application/x-www-form-urlencoded或multipart/form-data风格的键值对JavaScript 提供了原生对象FormData来封装待发送信息它的最大好处是传入一个表单元素所有字段会被自动提取为键值对。完整示例一个最强动物投票表单先看 HTML 部分——一个用单选按钮投票、附带姓名输入框的表单h2Which one is the strongest?/h2 form p input typeradio namestrongest idelephant valueELE checked label forelephantThe elephant/label br input typeradio namestrongest idrhinoceros valueRHI label forrhinocerosThe rhinoceros/label br input typeradio namestrongest idhippopotamus valueHIP label forhippopotamusThe hippopotamus/label br /p p label fornameYour name/label: input typetext namename idname required /p input typesubmit valueVote /form p idresult/p注意每个输入控件的name属性——strongest与name——它们正是之后FormData自动生成的键名。配套的 JavaScript 负责接管表单提交// Handle form submission document.querySelector(form).addEventListener(submit, e { // Cancel default behavior of sending a synchronous POST request e.preventDefault(); // Create a FormData object, passing the form as a parameter const formData new FormData(e.target); // Send form data to the server with an asynchronous POST request fetch(https://thejsway-server.herokuapp.com/animals, { method: POST, body: formData }) .then(response response.text()) .then(result { document.getElementById(result).textContent result; }) .catch(err { console.error(err.message); }); });这段代码的执行链路可以拆解为四步e.preventDefault()拦截默认行为表单的原生提交会发起一个同步的POST请求并整页刷新传统 Web 开发模型见 第 20 章。这里先取消它改用 AJAX 异步模型。new FormData(e.target)自动抓取字段e.target即触发事件的表单元素。FormData构造器会读取表单内所有带name的控件自动生成strongestELE、nameBaptiste这类键值对。fetch()发起异步 POSTfetch()的第二个参数是配置对象method: POST指定 HTTP 方法body: formData把表单数据放入请求体。这也是 第 21 章 学过的fetch(url)调用方式的进阶形态——fetch()默认是GET要发数据必须显式传第二个参数。异步更新页面response.text()读取服务器返回的文本这是Response对象的方法返回一个 promise详见 第 21 章随后把结果写入result元素实现不刷新页面的局部更新。提交后服务器回显了投票人姓名与所选项页面底部显示确认信息脱离表单手动append()键值对FormData并非表单的专属品——它完全可以脱离任何form独立使用手动append()任意键值对。下面是一个只有按钮的极简页面button idbuyButtonBuy a new t-shirt/button p idresult/pdocument.getElementById(buyButton).addEventListener(click, () { // Create a new, empty FormData object const formData new FormData(); // Fill the object with key/value pairs formData.append(size, L); formData.append(color, blue); // Send data to the server fetch(https://thejsway-server.herokuapp.com/tshirt, { method: POST, body: formData }) .then(response response.text()) .then(result { document.getElementById(result).textContent result; }) .catch(err { console.error(err.message); }); });用户点击按钮时程序创建一个空FormData对象用append(size, L)、append(color, blue)填入两对自定义数据再以POST发送。服务器端收到后回执确认从源码结构看FormData.append(key, value)是填充数据的主入口需要发送多个同名字段例如多选复选框时也可以重复调用append()同名键。这个模式非常适合非表单来源的数据上报场景比如按钮点击、键盘事件或定时任务触发的数据采集。发送 JSON 数据结构化信息的正确打开方式当服务器期望的数据更结构化——包含数组、嵌套对象、复杂类型——键值对就显得力不从心此时JSON是更合适的载体。完整示例向服务器发送一个汽车数组下面的 JavaScript 构造了一个包含两个对象的数组每辆车都有model、color、registration字段以及一个嵌套的checkups年检记录数组// Create an array containing two objects const cars [ { model: Peugeot, color: blue, registration: 2012, checkups: [2015, 2017] }, { model: Citroën, color: white, registration: 1999, checkups: [2003, 2005, 2007, 2009, 2011, 2013] } ]; // Send this array as JSON data to the server fetch(https://thejsway-server.herokuapp.com/api/cars, { method: POST, headers: { Accept: application/json, Content-Type: application/json }, body: JSON.stringify(cars) }) .then(response response.text()) .then(result { console.log(result); }) .catch(err { console.error(err.message); });与FormData路径相比这里多了两个关键动作JSON.stringify(cars)序列化正如 第 21 章 所讲JSON.stringify()把 JavaScript 对象/数组转换为 JSON 字符串。fetch()的 body 只能是字符串或FormData等特定类型所以必须先序列化。headers声明数据类型Content-Type: application/json告诉服务器请求体是 JSONAccept: application/json表示我期望 JSON 响应。服务器依据Content-Type决定如何解析请求体这两个请求头是 JSON 交互的标配。服务器收到后在控制台回显了完整数据为什么 JSON 更适合结构化数据对比两条路径可以发现分工明确FormData天然是扁平键值对适合表单字段、简单选项上报JSON 能无损表达嵌套结构——如上例的checkups数组、未来可能出现的对象套对象——并且与 JavaScript 对象字面量语法同源第 20 章 对 JSON 的定义一组双引号包裹的 name/value 对值可以是数字、字符串、布尔值、数组或对象。实务上的选择标准就是文档开头那句话数据格式取决于服务器期望什么。一般规律是——表单直接提交用FormData复杂业务数据用 JSON。TL;DR 速查两种发送方式的核心代码方式一发送 HTML 表单数据或键值对// Create a FormData object containing the HTML form data const formData new FormData(myForm); // Send form data to the server with an asynchronous POST request fetch(https://my-server-url, { method: POST, body: formData }) .then();方式二发送自定义键值对// Create a new, empty FormData object const formData new FormData(); // Fill the object with key/value pairs formData.append(size, L); formData.append(color, blue); // ...方式三发送结构化 JSON 数据// Create some JavaScript data const myData { // ... }; // Send this data as JSON to the server fetch(https://my-server-url, { method: POST, headers: { Accept: application/json, Content-Type: application/json }, body: JSON.stringify(myData) }) .then();三条路径共用一个骨架fetch(url, { method: POST, ... })发起异步 AJAX 调用即 HTTP POST 请求区别只在于 body 的构造方式与 headers 的声明。这也是整章的核心公式。Coding time两道实战练习题本章配套两个练习建议打开浏览器开发者工具Console 与 Network 面板边做边验证。练习一New article发布新文章编写 HTML提供两个输入字段分别填写新文章blog article的标题title与内容content编写 JavaScript将两个字段以表单数据form data形式发送到https://thejsway-server.herokuapp.com/articles服务器会返回一条确认消息把它显示在页面上。⚠️警告该 URL只接受POST请求——用GET访问会失败这正好呼应了本章发数据必须用 POST的主旨。这道题的思路与投票表单完全一致new FormData(form)自动抓取title、content两个字段 →fetch(..., { method: POST, body: formData })→ 用response.text()读取确认信息并写入页面。注意表单中name属性必须与服务器期望的字段名title、content一致这是服务端解析的契约。练习二Visited countries发送旅行足迹目标把旅行信息发送给服务器数据格式是一个 JSON 对象包含两个字段name你的名字值为字符串countries你访问过的国家列表值为对象数组。每个对象含name字段字符串国家名与year字段整数最近一次到访年份。预期提交的数据结构如下示例访问了意大利与爱尔兰const traveler { name: Sam, countries: [ { name: Italy, year: 2022 }, { name: Ireland, year: 2021 }, { name: USA, year: 2021 } ] };勘误提示原书此处示例对象中Italy之后的两个条目误用了model/color键名疑似从本章汽车 JSON 示例复制而来这与题目要求的name/year字段不一致。按题目规范每个国家对象都应使用name与year两个键服务器才能正确解析。发送地址为https://thejsway-server.herokuapp.com/api/countries服务器返回确认消息后把它输出到控制台。这道题必须走 JSON 路径题目明确要求 JSON 对象所以答案骨架应参照发送 JSON 数据一节JSON.stringify(traveler)序列化 →headers声明Content-Type: application/json→.then(result console.log(result))把确认信息打到控制台。本章在全书中的位置与延伸阅读本章属于书中「Build web applications构建 Web 应用」板块在 mkdocs.yml 的导航结构中紧随 第 21 章查询 Web 服务器、fetch()与 Promise 基础与 第 22 章消费 Web API之后。它与前几章构成一条完整的 AJAX 知识链第 20 章HTTP 协议、POST方法、JSON 格式与 AJAX 模型——本章的理论地基第 21 章fetch()的then()/catch()、Promise 三态、Response.text()/Response.json()、JSON.parse()/JSON.stringify()——本章用到的全部异步与序列化工具第 22 章读取 API 的GET请求、请求头Accept语义——与本章的POST请求互为镜像。书中的示例服务器https://thejsway-server.herokuapp.com同时提供读/api/articles第 22 章与写/animals、/tshirt、/api/cars、/articles、/api/countries本章两类接口是练习 AJAX 双向通信的现成沙箱。若想继续深入下一章 第 24 章 将介绍 Node.js——书中自己动手实现这类 API 服务的伏笔第 22 章预告的upcoming chapter正是从这里开始。赞分享教程文档【免费下载链接】thejswayThe JavaScript Way book项目地址https://gitcode.com/gh_mirrors/th/thejsway点击查看免费下载相关推荐The JavaScript Way 第 20 章Web 开发基础——HTTP、AJAX 与 JSON 全解析The JavaScript Way 第 20 章Web 开发基础——HTTP、AJAX 与 JSON 全解析 本篇技术指南基于开源书籍 The JavaSc教程文档3分钟搞定国家中小学智慧教育平台电子课本下载终极指南3分钟搞定国家中小学智慧教育平台电子课本下载终极指南 还在为无法下载国家中小学智慧教育平台的电子课本而烦恼吗tchMaterial parser这款智能下载网页爬虫教育Slug安全最佳实践如何保护你的短链服务免受滥用Slug安全最佳实践如何保护你的短链服务免受滥用 短链接服务在现代网络中扮演着重要角色但也面临着被滥用的风险。Slug作为一款基于T3 Stack构建的开源上一篇ClassifAI核心功能揭秘从标题生成到OCR15个AI工具一次掌握下一篇10分钟搭建个人专属图床ImgURL超详细部署教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表