【问题标题】:How 2D array is handled in HTTP POST requestHTTP POST 请求中如何处理二维数组
【发布时间】:2015-10-13 05:26:02
【问题描述】:

我有一个如下所示的 HTML 表单,它使用二维数组来存储输入元素

<form action="/myAction" method="post">
  <input type="text" name="myList[1][NAME]" value="John" />
  <input type="text" name="myList[1][AGE]" value="20" />
  <input type="text" name="myList[2][NAME]" value="Mike" />
  <input type="text" name="myList[2][AGE]" value="30" />
  <input type="text" name="myList[3][NAME]" value="Sam" />
  <input type="text" name="myList[3][AGE]" value="40" />
  <input type="submit" value="submit" />
</form>

我想知道在 HTTP 请求中将传递多少个参数,是一个还是六个。如何编写表单,以便将以上 6 个键值对作为一个参数传递。

感谢您的意见。

编辑:看起来下面的请求是在请求中发送 6 个参数,我怎样才能只为下面的表单发送参数

<form action="/myAction" method="post">
  <input type="text" name="myList[]" value="John" />
  <input type="text" name="myList[]" value="Peter" />
  <input type="text" name="myList[]" value="Mike" />
  <input type="text" name="myList[]" value="Neo" />
  <input type="text" name="myList[]" value="Stella" />
  <input type="text" name="myList[]" value="Eve" />
  <input type="submit" value="submit" />
</form>

【问题讨论】:

  • 我想知道 HTTP 请求中将传递多少个参数:查看开发者工具的网络选项卡或使用代理,如 Fiddler
  • 这就是接收语言如何解析发布数据的全部内容。您使用的是哪种语言或 http 服务器库?

标签: javascript html arrays post multidimensional-array


【解决方案1】:

更好的做法是将数组制作成 JSON 对象并传递。

【讨论】:

    【解决方案2】:

    默认情况下,表单将使用application/x-www-form-urlencoded 内容类型提交,因此您的数据将通过these 规则进行URI 编码。

    编码:

    myList%5B%5D=John&myList%5B%5D=Peter&myList%5B%5D=Mike&myList%5B%5D=Neo&myList%5B%5D=Stella&myList%5B%5D=Eve

    解码:

    myList[]=John&myList[]=Peter&myList[]=Mike&myList[]=Neo&myList[]=Stella&myList[]=Eve

    如果您只想提交一个参数,则应在客户端对数据进行编码,例如您可以用逗号分隔所有值。

    这是一个工作示例(使用 jQuery):

    $('form').submit(function(e) {
        processFormSubmission(this);
    });
    
    function processFormSubmission(formElem) {
        var arr = [];
        $(formElem).find(':input').each(function(i) {
            $(this).attr('disabled', 'disabled');    // prevent from submitting
            if( $(this).is(':submit') ) return true; // skip submit input field
            arr.push(this.value);
        });
        $('<input>').attr({type: 'hidden', name: '_data', value: arr.join(',')}).appendTo(formElem);
    }
    

    以上代码将创建隐藏的_data输入,并将disabled属性添加到其他输入字段,因此它们不会提交到服务器。

    _data=John,Peter,Mike,NeoStella,Eve

    在服务器端,您应该解码该数据,例如像这样:

    // var_dump( $_POST );
    
    if( ! empty( $_POST['_data'] ) {
        $myList = explode(',', $_POST['_data']);
        // var_dump( $myList );
    }
    

    【讨论】:

    • 感谢您的回复,您能告诉我如何在客户端对数据进行编码吗?如何将 myList 转换为 CSV,当我尝试 join() 或 toString() 时,它会将整个输入元素字符串化,而我只希望值存在。
    • 谢谢,我也找到了解决方法。
    • 很高兴听到!顺便问一下,你的解决方法是什么? :)
    • @unixarmy .slice(',')arr.slice(',') 的目的是什么?
    • @guest271314,好收获!我更新了代码,arr.join(','); 是应该使用的正确方法。
    【解决方案3】:

    HTTP 参数中数组的使用特定于客户端和/或服务器端实现。 HTTP 协议中没有数组(包括 POST 和 GET),甚至没有键/值格式(参见RFC)。

    键/值标准由HTML 通过使用&lt;form&gt; 定义。当方法为 POST 时,HTTP 查询正文包含类型为application/www-form-urlencoded 的“一些数据”。

    在第一个示例中,HTML 将为每个 input 字段设置一个键/值对。

    [] 字符从 HTTP 协议的角度来看只是随机字节,只是 HTML 键/名称的一部分。

    HTTP 查询如下所示:

    [...]
    Content-Type: application/x-www-form-urlencoded
    
    myList%5B1%5D%5BNAME%5D=John&myList%5B1%5D%5BAGE%5D=20&myList%5B2%5D%5BNAME%5D=Mike&myList%5B2%5D%5BAGE%5D=30&myList%5B3%5D%5BNAME%5D=Sam&myList%5B3%5D%5BAGE%5D=40
    

    现在,问题是:

    我想知道在 HTTP 请求中将传递多少个参数。

    HTTP 请求中总是有一个(或没有)查询字符串和一个(或没有)正文。所以,这个问题本身并没有真正的意义。如果更多的是关于 HTML,答案是六。 一个输入字段 = 一个键/值对 = 一个特定信息。要拥有多个信息,您需要多个输入字段。

    我假设你正在使用 PHP,它解析 [] 字符,所以从 PHP 的角度来看,你会得到这样的结构:

    Array
    (
        [myList] => Array
            (
                [1] => Array
                    (
                        [NAME] => John
                        [AGE] => 20
                    )
                [2] => Array
                    (
                        [NAME] => Mike
                        [AGE] => 30
                    )
                [3] => Array
                    (
                        [NAME] => Sam
                        [AGE] => 40
                    )
            )
    )
    

    关于另一个问题:

    我怎样才能只为下面的表格发送参数

    <form action="/myAction" method="post">
      <input type="text" name="myList[]" value="John" />
      <input type="text" name="myList[]" value="Peter" />
      <input type="text" name="myList[]" value="Mike" />
      <input type="text" name="myList[]" value="Neo" />
      <input type="text" name="myList[]" value="Stella" />
      <input type="text" name="myList[]" value="Eve" />
      <input type="submit" value="submit" />
    </form>
    

    六个输入 = 六个信息 = 六个键/值。但是 PHP 会给你一个包含六个值的数组。 或者也许你只需要一个&lt;select&gt;

    如果您没有使用 PHP,那么它特定于您使用的语言,所以请澄清问题。

    【讨论】:

      【解决方案4】:

      这实际上是一个非常有用的功能。如果您仔细观察,您会发现它实际上非常接近 PHP 本身的数组操作方式。

      <input type="text" name="myList[]" value="John" />
      <input type="text" name="myList[]" value="Peter" />
      <input type="text" name="myList[]" value="Mike" />
      

      $myList = [];
      $myList[] = "John";
      $myList[] = "Peter";
      $myList[] = "Mike";
      

      它的设计使您可以使用输入的name 属性轻松创建 PHP 数组,示例

      <input type="text" name="myList[user][100505][name]" value="John" />
      

      如果你在 PHP 中定义它会是一样的

      $_POST['myList']['user']['100505']['name'] = 'John';
      

      为了让您的 PHP 模块填充 $_POST 数组,您需要发送两个 Content-Type 标头之一:application/x-www-form-urlencodedmultipart/form-data; boundary-...,您的浏览器会自动执行这些标头。如果您注意请求正文,您会注意到参数的定义与输入字段的命名完全相同,这意味着它们将以完全相同的顺序使用相同的值进行解析。

      考虑以下示例:

      <input type="text" name="myList[]" value="John" />
      <input type="text" name="myList[]" value="Peter" />
      <input type="text" name="myList[]" value="Mike" />
      

      这将导致一个包含 3 个元素的数组,但是

      <input type="text" name="myList[1]" value="John" />
      <input type="text" name="myList[1]" value="Peter" />
      <input type="text" name="myList[1]" value="Mike" />
      

      这将产生一个只有一个元素的数组,即Mike,因为参数是按照提供的顺序进行解析的,并且由于它们都有相同的键,所以最后一个就是你得到的那个。另外,不要被愚弄你只得到一个元素,所有元素都由请求携带并传递给服务器,即使你有 1000 个输入,你仍然会在你的 $_POST['myList'] 中得到 1 个元素,但所有 1000 个都会被解析。

      您可以继续使用任意数量的级别,请记住,这样做时,如果您有大量此类输入和大量数组级别,这可能会增加请求尺寸明显。另请注意,从 PHP 7.0(尚未发布)起,出于安全目的,参数的数量将限制为 1000 - 即 DoS 攻击,它利用此弱点并发送服务器将尝试解析的大量参数,消耗资源。

      【讨论】:

      • 我相信@php_nub_qq 是在正确的轨道上。 OP 没有在问题中指定您的后端技术,但可以安全地假设它是 PHP,因为表单输入的命名方式以及 PHP 自动将它们转换为数组的方式。
      【解决方案5】:

      响应将如下所示

      Array
      (
          [myList] => Array
              (
                  [1] => Array
                      (
                          [NAME] => John
                          [AGE] => 20
                      )
                  [2] => Array
                      (
                          [NAME] => Mike
                          [AGE] => 30
                      )
                  [3] => Array
                      (
                          [NAME] => Sam
                          [AGE] => 40
                      )
              )
      )
      

      编辑:为了更具体地回答您的问题,响应中只有一个参数,但该参数将是一个数组。数组的每个元素本身就是一个数组(请注意,这是一个数组数组,技术上不是二维数组,这并不完全相同)。

      通常你的模型很好,这些数据在服务器端很容易处理。

      【讨论】:

        猜你喜欢
        • 2010-12-08
        • 1970-01-01
        • 2014-05-05
        • 1970-01-01
        • 2017-12-29
        • 1970-01-01
        • 1970-01-01
        • 2014-07-13
        相关资源
        最近更新 更多