如何优雅的获取Form表单数据?

简介: 如何优雅的获取Form表单数据?

先看一个简单的例子


比如这里有一个简单的 form 表单

<form id="form">
    <input name="user" type="text">
    <div>
        <input type="radio" name="A" value="r1">r1
        <input type="radio" name="A" value="r2">r2
        <input type="radio" name="A" value="r3">r3
        <input type="radio" name="A" value="r4">r4
    </div>
    <div>
        <input type="checkbox" name="B" value="c1">c1
        <input type="checkbox" name="B" value="c2">c2
        <input type="checkbox" name="B" value="c3">c3
        <input type="checkbox" name="B" value="c4">c4
    </div>
    <button type="submit">login</button>
    <button type="reset">reset</button>
</form>


页面如下

image.png

现在,随便输入点内容

image.png

如果提交,表单会触发默认行为,直接以get方式提交到当前页

image.png

可以看到这些参数正是我们输入的参数。


表单的默认行为


通常我们都会把这些默认行为阻止掉,毕竟都不希望在提交表单会跳转到另一个页面,或者刷新整个页面

form.addEventListener("submit", (ev) => {
    ev.preventDefault();
    // 自己发请求
})


那么,我需要如何拿到这些提交的值呢?


表单提交的数据类型


根据数据类型来划分,通常使用的表单提交数据格式大概有以下几种


  1. formdata格式,需要通过 new FormData 创建
  2. json格式,形如{ a:1,b:2,c=3 }
  3. url字符串拼接,形如 a=1&b=2&c=3


1.formdata


通常 formdata 的使用方式如下

var formData = new FormData();
formData.append('username', 'xboxyan');
formData.append('password', '123456');


但是对于 form 来说,大可以不必采用这样的方式,直接通过以下方式获取

var formData = new FormData(form); // form为表单对象


所以,针对表单容器就不要再用 div 了!


为了更加方便的使用,这里简单扩展一下 form 属性

/* formdata */
Object.defineProperty(HTMLFormElement.prototype, 'formdata', {
    get() {
        return new FormData(this);
    }
})


这样就可以通过form.formdata来获取了

image.png

FormData对象的值是不可见的,需要通过get方式才能看到


image.png

关于 FormData 的更多操作可参考 https://developer.mozilla.org...


2.jsondata


json 格式也是非常常用的一种数据传递方式了,不过原生 form 并没有直接获取的方式,只能自己封装了。


这里可以直接在上面 FormData 的基础上遍历一次即可,由于有些值会有多个,比如上面的多选框,这里直接转成了数组,具体实现如下

/* jsondata */
Object.defineProperty(HTMLFormElement.prototype, 'jsondata', {
    get() {
        const jsondata = {}
        const formdata = new FormData(this);
        formdata.forEach((value, key) => {
            if (!jsondata[key]) {
                jsondata[key] = formdata.getAll(key).length > 1 ? formdata.getAll(key) : formdata.get(key);
            }
        });
        return jsondata;
    }
})


这样就可以通过form.jsondata来获取了

image.png

3.urldata


还有一种方式在get请求中会用到,就是 url拼接方式,这个原生也没有直接的方案,可以借助上面jsondata转换一下,这里做了一个小改动,比如默认的多选是

b=1&b=2&b=3&c=1,这里改造成了b=1,2,3&c=1,具体实现如下

/* urldata */
Object.defineProperty(HTMLFormElement.prototype, 'urldata', {
    get() {
        const urldata = [];
        Object.entries(this.jsondata).forEach(([key, value]) => {
            urldata.push(key + '=' + (value.join ? value.join() : value))
        })
        return urldata.join('&');
    }
})


这样就可以通过form.urldata来获取了


image.png

总结


通过以上3个方法,基本可以满足日常开发的绝大部分需求,前提是 html 足够规范,表单就必须是 form,单选就必须是 input radio等等,很多前端同学或者说很多框架都喜欢用 div 来模拟,以至于这些原生特性就直接被抛弃掉了,岂不可惜?


最后,附上以上全部源码

/* jsondata */
Object.defineProperty(HTMLFormElement.prototype, 'jsondata', {
    get() {
        const jsondata = {}
        const formdata = new FormData(this);
        formdata.forEach((value, key) => {
            if (!jsondata[key]) {
                jsondata[key] = formdata.getAll(key).length > 1 ? formdata.getAll(key) : formdata.get(key);
            }
        });
        return jsondata;
    }
})
/* formdata */
Object.defineProperty(HTMLFormElement.prototype, 'formdata', {
    get() {
        return new FormData(this);
    }
})
/* urldata */
Object.defineProperty(HTMLFormElement.prototype, 'urldata', {
    get() {
        const urldata = [];
        Object.entries(this.jsondata).forEach(([key, value]) => {
            urldata.push(key + '=' + (value.join ? value.join() : value))
        })
        return urldata.join('&');
    }
})


相关文章
|
JavaScript
|
2月前
|
IDE JavaScript 前端开发
【全网最详细】VS2022下载、安装、使用一篇搞定(附社区版安装包)
Visual Studio 2022(VS2022)是微软推出的首个原生64位IDE,突破4GB内存限制,性能更强。支持C/C++、C#、Python、JavaScript等多语言,提供免费社区版(功能完整)、专业版和企业版。推荐初学者与个人开发者使用社区版,安装灵活、学习成本低,是高效开发的理想选择。(239字)
|
关系型数据库 MySQL Linux
Navicat15连接本地虚拟机的Mysql(Centos7)
Navicat15连接本地虚拟机的Mysql(Centos7)
1347 0
Navicat15连接本地虚拟机的Mysql(Centos7)
安全 定位技术 API
4869 0
|
移动开发 JavaScript 小程序
uView Tabs 标签
uView Tabs 标签
628 0
|
安全 Java 数据库
第16课:Spring Boot中集成 Shiro
第16课:Spring Boot中集成 Shiro
1241 0
|
小程序
小程序对接视频号插件使用流程
小程序与视频号的深度关联,为内容创作者和商家提供了更丰富的流量入口和互动场景。本文将详细介绍如何将小程序与视频号进行关联,跳转至视频号主页。
777 5
|
11月前
|
Kubernetes Cloud Native 异构计算
133_云端扩展:Kubernetes scaling - 设置自动缩放的阈值与LLM部署最佳实践
在大语言模型(LLM)部署的时代,如何高效地管理计算资源、应对动态负载并优化成本,成为了每个AI工程师必须面对的挑战。随着LLM应用的普及,用户请求模式变得日益复杂且难以预测,传统的静态资源配置方式已无法满足需求。Kubernetes作为云原生时代的容器编排平台,其强大的自动扩展能力为LLM部署提供了理想的解决方案。
656 2
|
缓存 监控 安全
Spring AOP 详细深入讲解+代码示例
Spring AOP(Aspect-Oriented Programming)是Spring框架提供的一种面向切面编程的技术。它通过将横切关注点(例如日志记录、事务管理、安全性检查等)从主业务逻辑代码中分离出来,以模块化的方式实现对这些关注点的管理和重用。 在Spring AOP中,切面(Aspect)是一个模块化的关注点,它可以跨越多个对象,例如日志记录、事务管理等。切面通过定义切点(Pointcut)和增强(Advice)来介入目标对象的方法执行过程。 切点是一个表达式,用于匹配目标对象的一组方法,在这些方法执行时切面会被触发。增强则定义了切面在目标对象方法执行前、执行后或抛出异常时所
18211 5

热门文章

最新文章