面试题 - 三种表单序列化的方式及序列化后追加参数原理

面试题 - 三种表单序列化的方式及序列化后追加参数原理

表单提交的原则

在这里插入图片描述

  • 提交结果
    在这里插入图片描述
结论一:name相同的表单提交格式

如果name值相同的表单提交,该name值会出现多次,且对应不同表单的值

结论二:没有name的表单、disabled的表单

表单元素没有name属性、含有disabled属性都会被禁止提交

在进行表单控制时,如果某一个表单即不可以被编辑但同时也需要被提交,可以设置readonly属性,通过给含有readonly属性的表单添加特定的css样式来模拟disabled的样式。

结论三:redio、checkbox选中值却没有value属性

如结果图所示:只会提示当前name表单为on,不会自动获取text的值。如果没有选中值,就不会提交该表单元素,即不会出现当前name表单为off的情况

结论四:被选中的option没有value属性

在这里插入图片描述
会提交该name表单,但是提交的值为空字符串

表单序列化的三种方式

serialize()

源码实现

function buildParams( prefix, obj, traditional, add ) {
    var name;
    if ( Array.isArray( obj ) ) {
        // Serialize array item.
        jQuery.each( obj, function( i, v ) {
            if ( traditional || rbracket.test( prefix ) ) {

                // Treat each array item as a scalar.
                add( prefix, v );

            } else {
                // Item is non-scalar (array or object), encode its numeric index.
                buildParams(
                    prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
                    v,
                    traditional,
                    add
                );
            }
        } );
    } else if ( !traditional && toType( obj ) === "object" ) {
        // Serialize object item.
        for ( name in obj ) {
            buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
        }

    } else {
        // Serialize scalar item.
        add( prefix, obj );
    }
}

jQuery.param = function( a, traditional ) {
    var prefix,
        s = [],
        add = function( key, valueOrFunction ) {
            // If value is a function, invoke it and use its return value
            var value = isFunction( valueOrFunction ) ?
                valueOrFunction() :
                valueOrFunction;
            s[ s.length ] = encodeURIComponent( key ) + "=" +
                encodeURIComponent( value == null ? "" : value );
        };

    if ( a == null ) {
        return "";
    }
    // If an array was passed in, assume that it is an array of form elements.
    if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
        // Serialize the form elements
        jQuery.each( a, function() {
            add( this.name, this.value );
        } );

    } else {
        // If traditional, encode the "old" way (the way 1.3.2 or older
        // did it), otherwise encode params recursively.
        for ( prefix in a ) {
            buildParams( prefix, a[ prefix ], traditional, add );
        }
    }
    // Return the resulting serialization
    return s.join( "&" );
};

serialize: function() {
    return jQuery.param( this.serializeArray() );
}

使用说明

  • 作用:对表单元素进行序列化处理,得到编码后的字符串
  • 使用方式:可是获取整个form表单的序列化值也可以获取单独某个表单元素的序列化值
  • 参数:无参数

代码示例

//username=Lucy&username=%E8%B7%AF%E8%A5%BF&sex=on&hobby=1&age=28&groups=groups1
$("#submitBtn").click(function() {
    let serialize = $("#form").serialize();
    console.log(serialize);
});

在这里插入图片描述

serializaArray()

源码实现

//rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
//rsubmittable = /^(?:input|select|textarea|keygen)/i;
serializeArray: function() {
    return this.map( function() {
        // Can add propHook for "elements" to filter or add form elements
        var elements = jQuery.prop( this, "elements" );
        console.log(elements)
        return elements ? jQuery.makeArray( elements ) : this; //获取form表单中的表单元素为数组
    } )
        //说明:无法序列化无name属性,disabled表单的原因
        .filter( function() {
        var type = this.type;
        return this.name && !jQuery( this ).is( ":disabled" ) &&
            rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
            ( this.checked || !rcheckableType.test( type ) );
    } )
        .map( function( i, elem ) {
        var val = jQuery( this ).val();

        if ( val == null ) {
            return null;
        }

        if ( Array.isArray( val ) ) {
            return jQuery.map( val, function( val ) {
                return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
            } );
        }

        return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
    } ).get();//get函数如果有参数获取数组值,如果无参数获取整个纯净的数组
}

使用说明

  • 作用:将表单元素转换为{name:name值,value:value值}格式的对象数组
  • 使用对象:可以获取整个表单元素的数组也可以获取单个表单元素的数组
  • 参数:无参数

使用示例

$("#primary").click(function() {
    let serializeArray = $("#form").serializeArray();
    console.log(serializeArray);
});

运行结果
在这里插入图片描述
在这里插入图片描述

serializeJSON()
  • jquery没有直接提供serializeJSON方法,但是提供了jquery.serializeJSON插件
    CDN链接地址
//或者直接引入该script标签
<script src="https://cdn.bootcss.com/jquery.serializeJSON/2.9.0/jquery.serializejson.min.js"></script>

使用说明

  • 作用:将表单元素转换为json格式的json字符串
  • 使用对象:可以获取整个表单元素的数组也可以获取单个表单元素的数组
  • 参数:无参数

使用示例

$("#success").click(function() {
    let serializeJson = $("#form").serializeJSON();
    console.log(serializeJson);
});

在序列化后添加参数

原理

由serialize函数的源码可以看出,序列化的本质在于对表单数组执行$.param()方法,对值进行编码拼接。所以单独的对对象进行编码拼接后和执行serialize函数得到的字符串格式是一致的。

实现
let param = $.param({param1:"参数1" , param2:"参数2"})+"&"+$form.serialize();

在这里插入图片描述

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值