【问题标题】:Multiple form fields with same 'name' attribute not posting具有相同“名称”属性的多个表单字段未发布
【发布时间】:2023-03-25 07:34:01
【问题描述】:

我正在处理一些遗留的 HTML/JavaScript。有些是我可以控制的,有些是从我无法控制的地方生成的。

有一个带有隐藏字段的动态生成的表单。表单本身是通过 Velocity 模板 (Percussion Rhythmyx CMS) 生成的,JavaScript 会插入额外的隐藏表单字段。最终结果是使用相同的“名称”属性生成的隐藏表单字段。数据被 POST 到 Java/JSP 服务器端代码,我对此知之甚少。

我知道共享相同“名称”属性的表单字段是有效的。由于某种原因,POST 的数据未被后端识别。 当我检查 POST 字符串时,same-name-keys 都不包含任何数据。

如果我在我的开发环境中操作代码,使得给定名称只存在一个输入字段,则数据将正确发布到后端。问题并不一致,有时,它工作得很好。

我能做些什么来保证数据会被发布吗?谁能想到它不会的原因?

I should really update my answer and post code here, because POST requests without 
variable strings indicates the problem is on the client side.

【问题讨论】:

  • 如果它真的只是一个简单的表单 POST,那么除非 JavaScript 代码禁用输入,否则它们会被发布。您可以使用 TamperData 之类的 Firefox 插件从浏览器的角度查看实际的 HTTP 请求。
  • 当您使用 POST 方法提交表单时,将使用项目的“名称”属性指定的变量名称传递字段。如果两个项目具有相同的名称,它们会尝试将数据存储在同一个变量中,因此数据将被重新分配。就像你做item1 = 'hello'; item1 = 'world';...最后一样,item1 将是“世界”。在您的情况下,变量的最后一个赋值可能是一个空白值。
  • @Travesty3 这完全取决于服务器代码。他说这里的服务器代码是Java/JSP,当有重复的参数名时,Java运行时会提供一个array的值。这些值不会被“重新分配”。
  • 您究竟是如何“检查” POST 数据的?
  • @Pointy:抱歉,不熟悉 JSP 的工作原理。我更像是一个 PHP 人,所以我认为它是一样的。

标签: javascript html jsp mootools


【解决方案1】:

你可以使用类似的东西:

var form = document.getElementById('yourformid');
var elements = form.getElementsByName('repeatedName');
var count = 0;
for(var item in elements){
   elements[item].name += count++;
}

这样您将获得每个隐藏字段的名称:

name0
name1
name2
...

【讨论】:

  • 应该不是必需的,因为服务器端代码会为 HTTP 请求中的重复参数名称呈现一组值。
  • 是的,不应该,但出于某种原因,这是他要求的
  • @AndréAlçadaPadez :不,这根本不是我想要的。虽然我很欣赏这种努力。 :-)
  • "我能做些什么来保证数据会被发布吗?" - 我认为至少这部分被涵盖了:)
  • @AndréAlçadaPadez:我没有测试过这个解决方案,但我假设它在技术上确实可以确保数据被发布。这是足够简单的代码。但它通过更改name 属性来实现。这将需要修改服务器端 Java 代码。反过来,这将需要生产服务器的主要版本。所有这些应该都是不必要的,因为生成的 HTML 是有效的。
【解决方案2】:

这个怎么样:

<script type="text/JavaScript">
    function disableBlankValues()
    {
        var elements = document.getElementById("form1").elements;
        for (var i = 0; i < elements.length; i++)
        {
            if (elements[i].value == "")
                elements[i].disabled = true;
        }
    }
</script>

<form action="page.php" method="POST" onsubmit="disableBlankValues()" id="form1">
    <input type="hidden" name="field1" value="This is field 1."/>
    <input type="hidden" name="field1" value=""/>
</form>


编辑

我现在意识到实际的问题(多个同名变量应该作为数组传递给 JSP),我的解决方案可能不是 OP 正在寻找的,但我将它留在这里以防万一发生帮助偶然发现这篇文章的其他人。

【讨论】:

    【解决方案3】:

    我已经制定了一个蛮力解决方案。请注意,我很清楚这是一个 hack。但是我陷入了不得不处理我无法控制的其他代码的境地。

    基本上,我创建了一个 ONSUBMIT 处理程序,它检查重复隐藏字段的表单并确保它们都填充了正确的数据。这似乎保证了 POST 字符串包含数据,无论表单如何呈现,Java 后端似乎也对此感到满意。

    我在以下情况下对此进行了测试:

    1. 代码生成隐藏字段的单个实例(有时确实会发生)
    2. 代码生成多个隐藏字段实例
    3. 代码不会生成隐藏字段的实例(不应该永远不会发生,但是嘿...)

    我的“else”条件包含一点点 MooTools 的魔力,但它是直截了当的东西。

    也许有一天其他人会发现这很有用...

    感谢您的帮助!

    <form method="post" name="loginform" id="loginform" action="/login" onsubmit="buildDeviceFP(this);">
        <script type="text/javascript">
            function insertFieldValues( fields, sValue )
            {
                if ( 'length' in fields ) 
                {
                    // We got a collection of form fields
                    for ( var x = 0; x < fields.length; x++ ) {
                        fields[x].value = sValue;
                    }
                }
                else
                {
                    // We got a single form field
                    fields.value = sValue;
                }
            }
    
            function buildDeviceFP( oForm )
            {
                // Get the element collections for Device Fingerprint & Language input fields from the form.
                var devicePrintElmts = oForm.elements.deviceprint;
                var languageElmts    = oForm.elements.language;
    
                // 'devicePrintElmts' & 'languageElmts' *should* always exist.  But just in case they don't...
                if ( devicePrintElmts) {
                    insertFieldValues( devicePrintElmts, getFingerprint() );
                } else if ( oForm.deviceprint ) {
                    oForm.deviceprint.value = getFingerprint();
                } else {
                    $('logonbox').adopt(
                        new Element( 'input', {'type':'hidden', 'name':'deviceprint', 'value':getFingerprint()} )
                    );
                }
    
                if ( languageElmts) {
                    insertFieldValues( languageElmts, getLanguage() );
                } else if ( oForm.language ) {
                    oForm.language.value = getLanguage();
                } else {
                    $('logonbox').adopt(
                        new Element( 'input', {'type':'hidden', 'name':'language', 'value':getLanguage()} )
                    );
                }
            }
        </script>
    

    【讨论】:

      猜你喜欢
      • 2011-01-13
      • 2017-11-06
      • 2016-06-02
      • 1970-01-01
      • 2011-01-18
      • 1970-01-01
      • 1970-01-01
      • 2017-03-03
      • 1970-01-01
      相关资源
      最近更新 更多