浏览器如何将数据发送给服务器:

  1. 对表单字段的名称和值进行URL编码,使用和号(&)分隔

  2. 不发送禁用的表单字段

  3. 只发送勾选的复选框和单选按钮

  4. 不发送type为“reset”和“button”的按钮

  5. 多选框中每个选中的值单独一个条目

  6. 在单击提交按钮提交表单的情况下,也会发送提交按钮。否则不发送提交按钮。也包括type为“image”的input元素

  7. select元素的值,就是选中的option元素的value特性值

实现表单序列化的代码:

function serialize(form) {
    var parts = [],
        field = null,
        i,
        len,
        j,
        optLen,
        option,
        optValue;

    for (var i = 0, len = form.elements.length; i < len; i++) {
        field = form.elements[i];

        switch (field.type) {
            case "select-one":
            case "select-multiple":

            if (field.name.length) {
                for (var j = 0, optLen = field.options.length; j < optLen; j++) {
                    option = field.options[j];
                    if (option.selected) {
                        optValue = "";
                        if (option.hasAttributes) {
                            optValue = ((option.hasAttributes("value")) ? option.value : option.text);
                        } else {
                            optValue = (option.attributes("value").specified ? option.value : option.text);
                        }
                        parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(optValue));
                    }
                }
            }
            break;

            case undefined:
            case "file":
            case "submit":
            case "reset":
            case "button":
                break;

            case "radio":
            case "checkbox":
                if (!field.checked) {
                    break;
                }
            //这里没有break
            default:
                if (field.name.length) {
                    parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(field.value));
                }
        }
    };
    return parts.join("&");
}

这个函数首先定义了一个名为parts的数组,用于保存要创建的字符串的各个部分;

然后通过for循环迭代每个表单字段,并将其保存在field变量中;

用switch语句检测type属性;

最麻烦的就是select元素,因为他有单选和多选之分,还要检查是否存在value值,如果不存在就获取其text值,在DOM兼容的浏览器中需要使用hasAttribute()方法,在IE中则需要使用specified属性;

对于fieldset元素,没有type属性就不需要序列化;

其他诸如按钮文件输入字段等等都要忽略;

最后对于单选按钮和复选框,要检查其checked属性是否为false,如果是则退出switch语句;如果为true,则继续执行default语句(所以checkbox的break行代码后面没有break,而是default);

default语句则是将当前字段的名称和值进行编码并添加到parts数组中;

最后就是利用join()函数格式化整个字符。


JS菌
6.4k 声望2k 粉丝