【问题标题】:How to fix duplicate form key post in form edit after free jqgrid upgrade免费jqgrid升级后如何在表单编辑中修复重复的表单键帖子
【发布时间】:2016-03-02 09:20:54
【问题描述】:

最新免费从 github 发布来自表单编辑的图像发送图像密钥两次。

例如使用下面的测试用例发布数据包含:

------WebKitFormBoundaryHjeY1fJPAaaXE56n
Content-Disposition: form-data; name="Pilt"; filename="eeva.bmp"
Content-Type: image/bmp


------WebKitFormBoundaryHjeY1fJPAaaXE56n
Content-Disposition: form-data; name="_image_Pilt"


------WebKitFormBoundaryHjeY1fJPAaaXE56n
Content-Disposition: form-data; name="Pilt"

注意name="Pilt" 出现了两次。

要重现,请在 Chrome 中打开下面的代码,选择行,开始表单编辑,选择一些图像,激活 chrome 开发人员工具,然后按提交按钮。 请求负载显示发布了重复的 Pilt 键。

如何解决这个问题,以使帖子上没有像早期版本一样的重复键?

测试用例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>http://stackoverflow.com/q/33628065/315935</title>
    <meta name="author" content="Oleg Kiriljuk">
    <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/redmond/jquery-ui.css">
    <link rel="stylesheet" href="http://netdna.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
    <!--<link rel="stylesheet" href="jqGrid/css/ui.jqgrid.css">-->
    <link rel="stylesheet" href="http://rawgit.com/free-jqgrid/jqGrid/master/css/ui.jqgrid.css">
    <style>
        html, body { font-size: 75%; }
    </style>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>

    <script src="http://malsup.github.io/jquery.form.js"></script>

    <script>
        $.jgrid = $.jgrid || {};
        $.jgrid.no_legacy_api = true;
        $.jgrid.useJSON = true;
    </script>
    <!--<script src="jqGrid/js/jquery.jqGrid.src.js"></script>-->
    <script src="http://rawgit.com/free-jqgrid/jqGrid/master/js/jquery.jqgrid.src.js"></script>
    <script>
    //<![CDATA[
    /*global $ */
    /*jslint browser: true */
    $(function () {
        "use strict";
        /*global $ */
        /*jslint plusplus: true, browser: true, eqeq: true */
        $(function () {
            "use strict";
            var mydata = [
                    { id: "10", _image_Pilt: null, invdate: "2013-11-01", name: "'", note: "note", amount: "200.00", tax: "10.00", closed: true, ship_via: "TN", total: "210.00" }
                ],
                editSettings = {


                    url: null,
                    useDataProxy: true,
                    dataProxy: function (opt, args) { dataProxyAjax(opt, args, 'Artpilt'); },


                    checkOnUpdate: true,
                    reloadAfterSubmit: false,
                    closeOnEscape: true,
                    savekey: [true, 13],
                    closeAfterEdit: true
                },
                addSettings = {
                    checkOnUpdate: true,
                    reloadAfterSubmit: false,
                    savekey: [true, 13],
                    closeOnEscape: true,
                    closeAfterAdd: true
                },
                delSettings = {
                },
                initDateEdit = function (elem) {
                    setTimeout(function () {
                        $(elem).datepicker({
                            dateFormat: "dd-M-yy",
                            showOn: "button",
                            changeYear: true,
                            changeMonth: true,
                            showButtonPanel: true,
                            showWeek: true
                        });
                    }, 50);
                },
                initDateSearch = function (elem) {
                    setTimeout(function () {
                        $(elem).datepicker({
                            dateFormat: "dd-M-yy",
                            changeYear: true,
                            changeMonth: true,
                            showButtonPanel: true,
                            showWeek: true
                        });
                    }, 50);
                },
                removeTheOptionAll = function (elem) {
                },
            dataProxyAjax = function (opts, act, entity) {
                //opts.url = $grid.jqGrid('getGridParam', 'url');
                if (opts.data._oper === "edit") {
                    opts.url = 'http://httpbin.org/status/200';
                }
                else {
                    opts.url = 'http://httpbin.org/status/201';
                }
                opts.iframe = true;
                var $form = $('#FrmGrid_' + $grid.jqGrid('getGridParam', 'id')),
                    ele;

                //use normal ajax-call when no files to upload
                //    if ($form.find(':file[value!=""]').size() == 0) {
                //        $.ajax(opts);
                //        return;
                //    }

                //Prevent non-file inputs double serialization
                ele = $form.find('INPUT,TEXTAREA,SELECT').not(':file');
                ele.each(function () {
                    $(this).data('name', $(this).attr('name'));
                    $(this).removeAttr('name');
                });

                //Send only previously generated data + files
                $form.ajaxSubmit(opts);
                //Set names back after form being submitted
                setTimeout(function () {
                    ele.each(function () {
                        $(this).attr('name', $(this).data('name'));
                    });
                }, 200);
            },

                $grid= $("#list")
                ;

            $("#list").jqGrid({
                useDataproxy: true,
                dataProxy: function (opt, args) { dataProxyAjax(opt, args, 'Artpilt'); },

                datatype: "local",
                data: mydata,
                colNames: ["", "Image","Select image", "Client", "Date", "Amount", "Tax", "Total", "Closed", "Shipped via", "Notes"],
                colModel: [
                    {name: "act", template: "actions"},


{    "label": "Pilt", "name": "_image_Pilt", "edittype": "image", "editoptions": {
        "src": ""
    }, "editable": true, "formatter": function (cell, options, row) {
        return '<img src=\"https://placehold.it/100x100\" />';
    }
, "search": false, "title": "", "width": 54
}, { "edittype": "file", "label": "", "name": "Pilt", "search": false, "title": "", "width": 54, "hidden": true, "editrules": { "edithidden": true }, "editable": true },

                    { name: "name", width: 60, editrules: { required: true } },
                    {name: "invdate", width: 80, align: "center", sorttype: "date",
                        formatter: "date", formatoptions: {newformat: "d-M-Y", reformatAfterEdit: true},
                        editoptions: {dataInit: initDateEdit, size: 14},
                        searchoptions: {dataInit: initDateSearch}},


                    {
                        name: "amount", width: 62, template: "number",
                        formatter: "number", formatoptions: { decimalSeparator: ",", thousandsSeparator: " ", decimalPlaces: 2, defaultValue: '0,00' },
                            editoptions: {
                                maxlength: 7,
                                type: "number",
                                max: "9999",
                                dataEvents: [
                                    {
                                        type: "blur",
                                        fn: function (e) {
                                                if (e.target.checkValidity()) {
                                                    $(e.target).removeClass("ui-state-error");
                                                } else {
                                                    $(e.target).addClass("ui-state-error");
                                                    alert(e.target.validationMessage);
                                                    $(e.target).focus();
                                                }
                                            }
                                    }
                                ]
                            }
                        },


                    //{ name: "amount", width: 70, formatter: "number", align: "right" },



                    { name: "tax", width: 50, formatter: "number", align: "right" },
                    {name: "total", width: 60, formatter: "number", align: "right"},
                    {name: "closed", width: 70, align: "center", formatter: "checkbox",
                        edittype: "checkbox", editoptions: {value: "Yes:No", defaultValue: "Yes"},
                        stype: "select",
                        searchoptions: {
                            sopt: ["eq", "ne"],
                            value: ":All;true:Yes;false:No",
                            dataInit: removeTheOptionAll
                        }},
                    {name: "ship_via", width: 100, align: "center", formatter: "select",
                        edittype: "select", editoptions: {value: "FE:FedEx;TN:TNT;IN:Intim", defaultValue: "TN"},
                        stype: "select",
                        searchoptions: {
                            sopt: ["eq", "ne"],
                            value: ":All;FE:FedEx;TN:TNT;IN:Intim",
                            dataInit: removeTheOptionAll
                        }},
                    {name: "note", width: 60, sortable: false, edittype: "textarea"}
                ],
                cmTemplate: {editable: true, searchoptions: {clearSearch: false }},
                rowNum: 10,
                rowList: [5, 10, 20],
                pager: true,
                gridview: true,
                rownumbers: true,
                autoencode: true,
                ignoreCase: true,
                sortname: "invdate",
                viewrecords: true,
                sortorder: "desc",
                caption: "Demonstrates implementating of local form editing",
                height: "100%",
                editurl: "http://httpbin.org/status/200",
                //editurl: "clientArray",
            }).jqGrid("navGrid", {}, editSettings, addSettings, delSettings, {
                multipleSearch: true,
                overlay: false,
                onClose: function () {
                    // if we close the search dialog during the datapicker are opened
                    // the datepicker will stay opened. To fix this we have to hide
                    // the div used by datepicker
                    $("div#ui-datepicker-div.ui-datepicker").hide();
                }
            }).jqGrid("filterToolbar", { defaultSearch: "cn" });
        });
    });
    //]]>
    </script>
</head>
<body>
    <div id="outerDiv" style="margin: 5px;">
        <table id="list"></table>
    </div>
</body>
</html>

【问题讨论】:

    标签: file-upload jqgrid form-submit ajaxform free-jqgrid


    【解决方案1】:

    您使用useDataproxy 选项。因此 jqGrid 根本不发送任何数据。如果存在一些问题,则可能在dataProxyAjax 的代码或jquery.form.js 的代码中。 jqGrid 只是准备postdata 对象中的数据。该对象仅包含一个名称为Pilt 的属性。因此,“重复表单密钥帖”的任何问题都可能不是免费 jqGrid 中的错误。

    如果您希望免费的 jqGrid 使用与以前相同的输出字符编码,则只需包含 autoEncodeOnEdit: true jqGrid 选项。此外,您可以通过serializeEditData 使用任何自定义编码。

    更新:问题在于使用jQuery.val() 填写添加/编辑表单的所有字段。引入这些更改是为了支持具有新类型值(numbercolorrange 等)的 HTML5 输入元素。作为副作用,jqGrid 填充了类型为imagefile 的字段。这是所报告问题的根源。

    发布the commit后问题应该会解决。

    【讨论】:

    • 如果使用 jqgrid 4.9.0(代码中的引用更改为github.com/free-jqgrid/jqGrid/blob/v4.9.0/js/…)发布作品没有问题。所以这是 jqgrid 问题。如何诊断或修复?
    • @Andrus:你在这两种情况下都检查了postdata()吗?你在哪里看到区别?您是否尝试使用 jqGrid 的autoEncodeOnEdit: true 选项?你有同样的结果吗?
    • 没有postdata:编辑表单元素是使用$('#FrmGrid_' + $grid.jqGrid('getGridParam', 'id')得到的,复制到iframe和iframe中的submit()被执行。 autoEncodeOnEdit: true 已使用,但问题仍然存在。
    • @Andrus:在我看来,我找到了原因。我会做一些改变,做一些测试,最后会附上我的答案。
    • .Answer 指出serializeEditData 可用于自定义编码。使用multipart/form-data 编码从表单编辑上传文件的最佳方式是什么?如果这是使用 serializeEditData,serializeEditData 如何将文件内容序列化为这种格式? serializeEditData 要求所有数据都必须在内存中。 stackoverflow.com/questions/33945491/…中有相关问题
    猜你喜欢
    • 1970-01-01
    • 2016-06-14
    • 2019-12-11
    • 2015-06-03
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 2013-05-26
    • 1970-01-01
    相关资源
    最近更新 更多