设计了一个简单的提交表单:

<form action="" method="post" enctype="application/x-www-form-urlencoded">
    <input type="hidden" name="action" value="{crypt_action('upgrate_member')}"/>
    <table class="upgrade_form" border="1" cellpadding="10">
        <tbody>
        <tr>
            <td width="324">公司名:<input type="text" name="member[company]" value="" style="width: 76%;"/></td>
            <td width="324">公司类型:{dselect($COM_TYPE, 'member[type]', '请选择', '', 'id="type"', 0)}</td>
            <td width="324">公司电话:<input type="text" name="member[telephone]" value="" style="width: 76%;"/></td>
        </tr>
        <tr>
            <td>公司成立年份:<input type="text" name="member[regyear]" value="" size="4" style="width: 26%;"/><span>(年份,如:2014)</span></td>
            <td>公司地址:<input type="text" name="member[address]" value="" style="width: 76%;"/></td>
            {php echo $CFD ? fields_html_particular('<td>', '</td>', array(), $CFD) : '';}
        </tr>
        <tr>
            <td colspan="3">主营行业:{category_checkbox("member[catid]", 4)}<span>(最多可选 6 个主营行业)</span>
            </td>
        </tr>
        <tr>
            <td colspan="3">主要经营范围:<input type="text" name="member[business]" value="" style="width: 90%;"/></td>
        </tr>
        <tr>
            <td colspan="3">
                <span style="float: left;">公司介绍:</span>
                <textarea name="member[content]" rows="5" maxlength="100" style="border: 0;width: 950px;"></textarea>
            </td>
        </tr>
        <tr>
            <td colspan="3"><input name="submit" type="submit" value="提交申请" /></td>
        </tr>
        </tbody>
    </table>
</form>

本来提交按照正常流程提交是没有问题的,但检查数据发现,以 checkbox 多选框展示的主营行业,只是一个数值,并不是数组。

原来是提交 checkbox 多选框的多个数值时,需要在每项的 name 属性后添加一个方括号 [],这样做的目的是让表单提交后这个字段在后台脚本接收时,自动合并成数组形式。

添加之后:

<td colspan="3">主营行业:{category_checkbox("member[catid][]", 4)}<span>(最多可选 6 个主营行业)</span></td>

再次提交,destoon 框架报错;HTTP 403 Forbddin - Bad Data。查找错误出处,原来 destoon 框架在接收客户端 $_GET/$_POST/$_REQUEST 数据时,会检查每一项的键值。对于 key 部分使用 strip_key 检查函数,它会遍历每一级的 key 值,看是否符合标准。而 member[catid][] 第二级数组 key 值为空,显然不符合,请求被驳回了。

框架为了安全考虑,form 表单中正常的 checkbox 传递数组方式就不能用了。这有点遗憾,但还是可以通过其他方式解决的,那就是使用一个 hidden 类型字段存储 checkbox 值(字符串拼接)。

<td colspan="3">主营行业:{category_checkbox("catid", 4)}<span>(最多可选 6 个主营行业)</span>
<input type="hidden" name="member[catid]" value=""/>
</td>

在表单提交之前,遍历 catid 值,拼接放到 member[catid] 隐藏字段中。

<form action="" method="post" enctype="application/x-www-form-urlencoded" onsubmit="beforeSubmit()">
...
<script type="application/javascript">
    function beforeSubmit() {
        var catid = [];
        $("input[name='catid']:checked").each(function(i){
            catid.push($(this).val());
        });
        $('input[name="member[catid]"]').val(catid.join(","));
        return true;
    }
</script>

通过修改函数 return 返回值,可以操控表单的提交和阻止提交。但是当 return 为 false 时,表单依然提交了

检查了一遍,原来 onsubmit 绑定的 handler 函数 beforeSubmit ,在绑定时也要调用 return,即 return beforeSubmit();

添加上 return,问题解决。

<form action="" method="post" enctype="application/x-www-form-urlencoded" onsubmit="return beforeSubmit()">
...