【问题标题】:Correct way to pass multiple values for same parameter name in GET request在 GET 请求中为相同参数名称传递多个值的正确方法
【发布时间】:2014-07-26 10:07:30
【问题描述】:

我正在研究在 GET 请求中为同一参数名称传递多个值的正确方法。

我见过这样的网址:

http://server/action?id=a&id=b

我见过这样的网址:

http://server/action?id=a,b

我的理解是第一个是正确的,但我找不到任何参考。我查看了 http 规范,但没有看到关于 URL 的“查询”部分应该如何构成的任何内容。

我不想要一个说“两者都可以”的答案 - 如果我正在构建一个 web 服务,我想知道这些方法中的哪一个是标准的,以便使用我的 web 服务的人知道如何为同名。

那么,有人可以指点我的官方参考来源来确认哪个选项是正确的吗?

【问题讨论】:

    标签: http get


    【解决方案1】:

    确实,没有明确的标准。要支持该信息,请查看维基百科的Query String 章节。有如下评论:

    虽然没有明确的标准,但大多数 Web 框架都允许 多个值与单个字段关联。[3][4]

    此外,当您查看RFC 3986 时,在3.4 Query 部分中,没有定义具有多个值的参数。

    大多数应用程序使用您显示的第一个选项:http://server/action?id=a&id=b。要支持该信息,请查看此Stackoverflow link 和此MSDN link,了解 ASP.NET 应用程序,它们对具有多个值的参数使用相同的标准。

    但是,由于您正在开发 API,我建议您做对您来说最简单的事情,因为 API 的调用者在创建查询字符串时不会遇到太多麻烦。

    【讨论】:

    • 在没有任何相反信息的情况下,我想你是对的——如果 RFC3986 没有指定标准,那么就没有标准。谢谢爱德华多。
    • A 建议使用 id=a&id=b 作为布尔 AND,id=a,b 作为布尔 OR。
    • FWIW PHP 不支持读取像 ?id=5&id=3 这样的参数。 PHP 只会在此处读取一个 id 值。如果我没记错的话,它必须看起来像这样才能与 PHP 一起使用:?id[]=5&id[]=3
    • +1 since you are developing the APIs, I suggest you to do what is the easiest for you, since the caller of the API will not have much trouble creating the query string.
    • id=a,b 假设逗号 , 是一个有效的分隔符。但是您的参数值可能包含,。那么客户端需要在查询参数值中转义,。但是您可以决定; 更好。这意味着客户端和服务器应该共享 API 的官方分隔符。 id=a&id=b 不存在这个问题,即使它使 url 更长
    【解决方案2】:

    我建议看看浏览器默认如何处理表单。例如,查看表单元素 <select multiple> 以及它如何处理 w3schools 中此示例中的多个值。

    <form action="/action_page.php">
    <select name="cars" multiple>
      <option value="volvo">Volvo</option>
      <option value="saab">Saab</option>
      <option value="opel">Opel</option>
      <option value="audi">Audi</option>
    </select>
    <input type="submit">
    </form>
    

    对于 PHP 使用:

    <select name="cars[]" multiple>
    

    Live example from above at w3schools.com

    从上面如果你点击“saab, opel”然后点击提交,会生成cars=saab&cars=opel的结果。然后根据后端服务器,参数 cars 应该作为一个数组出现,您可以进一步处理。

    希望这可以帮助任何寻找更“标准”方式来处理此问题的人。

    【讨论】:

      【解决方案3】:

      我正在描述一个在 Python(Django 框架)中运行非常顺利的简单方法。

      1.发送请求时,像这样发送请求

      http://server/action?id=a,b
      

      2。现在在我的后端,我使用一个总是创建一个列表的拆分函数拆分收到的值。

      id_filter = id.split(',')
      

      例子: 所以如果我在请求中发送两个值,

      http://server/action?id=a,b
      

      那么对数据的过滤器就是

      id_filter = ['a', 'b']
      

      如果我在请求中只发送一个值,

      http://server/action?id=a
      

      那么过滤结果是

      id_filter = ['a']
      

      3.要实际过滤数据,我只需使用 'in' 函数

      queryset = queryset.filter(model_id__in=id_filter)
      

      粗略地说,它执行的 SQL 等价于

      WHERE model_id IN ('a', 'b')
      

      第一个请求 并且,

      WHERE model_id IN ('a')
      

      第二个请求。

      这也适用于请求中的超过 2 个参数值!

      【讨论】:

      • 如果值本身有逗号怎么办?就像我可能有 2 个值一样:“abc”“p,q”
      • @VipulAgarwal 我要么,a)转义逗号。 b) 对逗号使用 ASCI 编码。 c) 使用不同的字符,;|¦¬ 等。 d) 在 API 文档中声明不能将逗号用于该查询参数....确实有 很多 处理方法有了这个,这与声明您想在查询参数中使用与号 (&amp;) 没有什么不同。所有相同的解决方法都适用于使用逗号。
      【解决方案4】:

      没有标准,但大多数框架都支持两者,例如 java spring,它同时接受 here

      @GetMapping("/api/foos")
      @ResponseBody
      public String getFoos(@RequestParam List<String> id) {
          return "IDs are " + id;
      }
      

      Spring MVC 将映射一个逗号分隔的 id 参数:

      http://localhost:8080/api/foos?id=1,2,3
      ----
      IDs are [1,2,3]
      

      或者单独的id参数列表:

      http://localhost:8080/api/foos?id=1&id=2
      ----
      IDs are [1,2]
      

      【讨论】:

      • 请不要只发布纯 URL。它们将来可能会失效。
      【解决方案5】:

      上述解决方案无效。它只是显示了最后的键/值对,但是这样做了:

      http://localhost/?key[]=1&key[]=2

      返回:

      Array
      (
      [key] => Array
          (
              [0] => 1
              [1] => 2
          )
      

      【讨论】:

        【解决方案6】:

        我的回答更倾向于PHP

        提交多值表单字段,即提交数组,可以通过几种不同的方式来完成,因为不一定要详细说明标准。

        发送多值字段或数组的三种可能方式是:

        • ?cars[]=Saab&cars[]=Audi(最佳方式 - PHP 将其读入数组)
        • ?cars=Saab&cars=Audi(不好的方式 - PHP 只会注册最后一个值)
        • ?cars=Saab,Audi(一般方式-您需要分解字符串以将值作为数组获取)

        例如:

        http://localhost:3000/foo?id[]=a&id[]=b

        返回

        Array
        (
          [id] => Array
             (
               [0] => a
               [1] => b
             )
        )
        

        (注意:在这种情况下,将查询键命名为 some_name[] 很重要,这样生成的请求变量将被 PHP 注册为数组)

        【讨论】:

          【解决方案7】:

          由于 url 是单个参数和多个值。 java中一个非常简单的解决方案是拆分字符串,然后将其附加到self.例如下面:

          String baseUrl = "http://server/action"
              String id = "a,b";
              StringBuilder url = new StringBuilder();
              url = baseUrl.append("?");
              String[] idArr = id.split(",");
                               StringBuilder sb = new StringBuilder();
                              for ( String fetchId : idArr) {
                                  sb.append("&id=").append(fetchId);
                                  url.append(sb);
                          }

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-08-22
            • 1970-01-01
            • 2015-01-14
            • 1970-01-01
            • 2014-02-27
            • 2020-09-11
            相关资源
            最近更新 更多