【问题标题】:jQuery deserialize formjQuery反序列化表单
【发布时间】:2011-08-09 07:11:57
【问题描述】:

我正在使用jQuery Serialize 序列化我的表单元素并希望将它们反序列化。不幸的是找不到任何有效的 jQuery 反序列化器,有什么建议吗?

【问题讨论】:

  • 您需要提供更多信息。你想在服务器上反序列化它们吗?在这种情况下,如果您告诉我们您正在使用什么,会有所帮助吗? Rails、PHP、ASP.net、Java?
  • 对不起,我忘了补充说我想在客户端使用 JS 反序列化数据。

标签: javascript jquery deserialization


【解决方案1】:

我编写了jQuery.deserialize 的一个版本,它支持从serialize、serializeArray 和serializeObject 函数生成的序列化数据。它还支持所有表单元素类型,包括复选框和单选按钮。

【讨论】:

  • 这是一个很棒的插件!感谢您提出一个。
  • 插件很棒!谢谢。
  • 嘿伙计。很棒的插件我只是想知道你的插件是否提供了一种我可以反序列化序列化数组并将其存储在变量中的方法
【解决方案2】:

试试这个:

function deparam(query) {
    var pairs, i, keyValuePair, key, value, map = {};
    // remove leading question mark if its there
    if (query.slice(0, 1) === '?') {
        query = query.slice(1);
    }
    if (query !== '') {
        pairs = query.split('&');
        for (i = 0; i < pairs.length; i += 1) {
            keyValuePair = pairs[i].split('=');
            key = decodeURIComponent(keyValuePair[0]);
            value = (keyValuePair.length > 1) ? decodeURIComponent(keyValuePair[1]) : undefined;
            map[key] = value;
        }
    }
    return map;
}

【讨论】:

  • 谢谢,对我有用
  • 简单实用。 +1
  • 太棒了!谢谢!
【解决方案3】:

我对尝试 JQuery.deserialize 非常感兴趣,但它似乎根本不处理复选框,所以它没有达到我的目的。所以我自己写了。结果比我想象的要容易,因为 jQuery val() 函数完成了大部分工作:

jQuery.fn.deserialize = function (data) {
    var f = this,
        map = {},
        find = function (selector) { return f.is("form") ? f.find(selector) : f.filter(selector); };
    //Get map of values
    jQuery.each(data.split("&"), function () {
        var nv = this.split("="),
            n = decodeURIComponent(nv[0]),
            v = nv.length > 1 ? decodeURIComponent(nv[1]) : null;
        if (!(n in map)) {
            map[n] = [];
        }
        map[n].push(v);
    })
    //Set values for all form elements in the data
    jQuery.each(map, function (n, v) {
        find("[name='" + n + "']").val(v);
    })
    //Clear all form elements not in form data
    find("input:text,select,textarea").each(function () {
        if (!(jQuery(this).attr("name") in map)) {
            jQuery(this).val("");
        }
    })
    find("input:checkbox:checked,input:radio:checked").each(function () {
        if (!(jQuery(this).attr("name") in map)) {
            this.checked = false;
        }
    })
    return this;
};

你应该可以这样使用:

$("#myform").deserialize(data);

其中 data 是一个参数列表,例如 $("#myform").serialize() 会产生什么。

它会影响表单中的所有字段,并且会清除数据中未包含的字段的值。但是您也可以传递任何选择器以仅影响特定字段,就像您可以使用序列化函数一样。例如:

$("select").deserialize(data);

【讨论】:

  • function decodeURIComponent() 在将+(加号)转换为` `(空格)时失败了。必须添加一些正则表达式来正确处理加号/空格。
  • @David162795,这是真的。当我使用这个函数时,我自己解决了这个问题:params.replace(/\+/g, "%20") 我从来没有把它添加到函数中,因为我不是 100% 确定它在所有情况下都有效(尽管我从来没有想过会出现这种情况一个问题)。这和你使用的正则表达式一样吗?
  • 这个函数反序列化到文档中的所有元素,重置所有具有匹配名称的复选框和字段。如果你反序列化空字符串,它还会重置页面中所有输入的值,名称为空。
  • @TiGR,本意是做序列化功能的反面。如果您执行 $("#myform").deserialize(data),它会影响表单中的所有字段(不是文档中的所有字段,如您所述)。但是您也可以传递任何选择器以仅影响特定字段。我刚刚更新了答案以更好地澄清这一点。
【解决方案4】:

一半的 jQuery Serialize 是 param(),所以反序列化查询字符串的一半将是一个 deparam。不幸的是,我无法找到一个好的独立 deparam。现在我建议获取jQuery BBQ library 并使用它。如果你不需要其他东西,你可以删除它们。我在某处读到 Ben Alman(牛仔)计划将 deparam 提取到自己的模块中。

对于反序列化的其余部分,您只需要遍历 deparam 返回的对象以及对象中的每个键值对,根据键选择表单元素,并将表单元素值设置为价值。

【讨论】:

    【解决方案5】:

    这个有点晚了,但有人可能会觉得这很有用。

    function fetchInput(identifier) {
        var form_data = identifier.serialize().split('&');
        var input     = {};
    
        $.each(form_data, function(key, value) {
            var data = value.split('=');
            input[data[0]] = decodeURIComponent(data[1]);
        });
    
        return input;
    }
    

    【讨论】:

    • 这对于一维数组来说已经足够好了;我会更改 input[decodeURIComponent(data[0])] = ... 以便像 users[]address[billing] 这样的键名也能正确解码。
    • 虽然我现在才注意到它不能很好地处理像 customers[] 这样的动态字段,在这些字段中,您可能有多个在服务器使用时生成数组。
    【解决方案6】:

    我现在不回答你的问题,但我的猜测是你想序列化它并发送回服务器,然后使用序列化的数据,这就是你必须反序列化它的原因吗?

    如果是这种情况,您应该考虑使用 .serializeArray()。您可以将其作为 ajax 中的 POST 数据发送,然后也可以稍后访问,因为您将拥有对象。

    【讨论】:

      【解决方案7】:

      可能有点晚了,但也许您正在寻找类似JQuery.deserialize 的东西。问题:不支持复选框或单选按钮。

      【讨论】:

        【解决方案8】:

        在 jQuery 中使用 Jack Allan 的 deparam 函数,您可以更改这一行:

        map[key] = value;
        

        $('input[name=' + key + ']').val(value);
        

        这会将数据加载回您的表单字段。

        【讨论】:

          【解决方案9】:

          当在序列化字符串中多次发现相同的键时,此代码返回一个数组

          
              chaine="single=Single1&multiple=Multiple&multiple=Multiple1&multiple=Multiple2&multiple=Multiple3&check=check2&radio=radio1"
              function deserialize(txt){
              myjson={}
              tabparams=chaine.split('&')
              var i=-1;
              while (tabparams[++i]){
              tabitems=tabparams[i].split('=')
              if( myjson[decodeURIComponent(tabitems[0])] !== undefined ){
                  if( myjson[decodeURIComponent(tabitems[0])] instanceof Array ){
                      myjson[decodeURIComponent(tabitems[0])].push(decodeURIComponent(tabitems[1]))
                  }
              else{
                 myjson[decodeURIComponent(tabitems[0])]= [myjson[decodeURIComponent(tabitems[0])],decodeURIComponent(tabitems[1])]
                      }
                  }
              else{
                   myjson[decodeURIComponent(tabitems[0])]=decodeURIComponent(tabitems[1]);
                  }
              }
              return myjson;
              }
          

          【讨论】:

            【解决方案10】:

            需要全部在一个字符串中,可以存储在 COOKIE 中,然后读取并使用输入值填写相同的表单。

            输入元素分隔符:~ (使用任何分隔符)

            输入属性分隔符:| (使用任何分隔符)

            输入类型|输入名称|输入值~输入2类型|输入2名称| input2 值

            var formData = '';
            $('#form_id').find('input, textarea, select').each(function(i, field) {
                formData += field.type+'|'+field.name+'|'+field.value+'~';
            });
            

            例子:

            hidden|vote_id|10~radio|option_id|~radio|option_id|427~radio|option_id|428~
            

            【讨论】:

              【解决方案11】:

              如果你想要删除标准的 URL 编码符号,你可以使用 JavaScript 的 decodeURIComponent(),它会给你一个常规的字符串,就像这样:

              var decodedString = decodeURIComponent("Http%3A%2F%2FHello%3AWorld");
              alert(decodedString);
              

              在这种情况下,decodedString 看起来像Http://Hello:World,这里是working fiddle

              在同一问题上进行了所有搜索,并在此处找到了答案:How can I decode a URL with jQuery?

              我知道这是一个老问题,但是对 jQuery deserialize 进行一些搜索让我来到这里,所以我不妨尝试为遇到相同问题的人提供不同的方法。

              【讨论】:

                猜你喜欢
                • 2011-08-01
                • 1970-01-01
                • 2010-12-20
                • 1970-01-01
                • 1970-01-01
                • 2011-03-26
                • 1970-01-01
                • 2015-07-02
                相关资源
                最近更新 更多