【问题标题】:How to send NULL in HTTP query string?如何在 HTTP 查询字符串中发送 NULL?
【发布时间】:2015-07-06 19:53:28
【问题描述】:

我正在开发一个 API,它可以接受主要的三种数据类型作为查询字符串参数的值:booleanstringnumericintegerfloat)。默认情况下,所有内容都检索一个字符串(我认为没有办法解决),但参数配置了一个类型,以便我将它们转换为正确的类型。

我现在需要开始接受 NULL 作为所有三种数据类型的值,但我不确定最好的方法是什么。

有些人似乎不接受任何值为 NULL(?param,没有 =),但这对我来说不太适用:

  1. 我已经接受 true 表示布尔值,尽管这可以更改。
  2. 它以空字符串的形式接收,这是string 数据类型的有效值。

所以,这是我能看到的仅有的两个选项,没有一个对我有用:

  1. 使用常量,如"NULL""~"。这适用于布尔值和数字,但不适用于字符串,因为这可能是所需的字符串值。
  2. 使用空值。再一次,这适用于布尔值和数字,但不适用于字符串,因为这可能是所需的字符串值。

似乎使用常量可能是我唯一的选择,为了避免字符串可以禁止常量的问题。但这真的是唯一可行的选择吗?我希望有更好的方法。 :(

编辑:我刚刚有了另一个可能可行的想法,但我不确定它会被如何看待。我认为它肯定违反了标准,很多人很可能不喜欢它,但它比迄今为止的任何其他解决方案都能更好地解决我的问题。基本上,这个想法是使用支持本机数据类型的 JSON。我对 POST 请求没有这个问题,因为它们使用的是 JSON。

因此,我们的想法是在查询字符串中采用 JSON,基本上允许使用替代查询字符串来覆盖标准 HTTP 字符串。类似:?_json={"foo":"bar","param":null} 而不是 ?foo=bar&param=~。或者甚至可以完全接管查询字符串:?{"foo":"bar","param":null}

【问题讨论】:

  • 你不能只发送一个 URLEncoded NUL 值吗? (%00)?由于它是一个查询参数,它在 URL 中,应该被解码。
  • Kylar 的建议似乎是被接受的方法。请参阅此处以供参考:w3schools.com/tags/ref_urlencode.asp
  • @Kylar:哇,谢谢,我从没想过,不知道这是公认的方法。介意将其发布为答案吗?我会接受它作为正确的解决方案。

标签: http standards


【解决方案1】:

为您专门设置为 null 的任何内容发送 URLEncoded NULL 值 (%00)。它应该是正确的 URL 解码。

【讨论】:

  • 在 PHP 中,它没有被正确解码。相反,它得到字符。但是通过与"\x00" 比较仍然可以捕捉到它。所以我不得不添加一个循环来检查每个查询参数并将"\x00"替换为null
  • 其实这里有一个比手动循环更好的实现:array_walk_recursive($queryParameters, function (&$value, $key) { if ($value === "\x00") { $value = null; } });
  • � 是默认的“未知/不可映射”Unicode 字符。您总是需要查看字节。 ;)
  • 哦,是的,别担心,我知道这一点。 :P 只是想提供信息以防对其他人有帮助。
  • %A0 为我工作。 %00 没用。喜欢:localhost/GetUsers/%A0/filter_value
【解决方案2】:

或者只是不发送任何值。在您的获取请求 url 中将查询参数值留空.. 像 -

API URL/?foo=&some_other_param=value

API 中的 foo 将被接收为 null

【讨论】:

  • 这是错误的。正如我在问题中所述,foo 将作为空字符串接收并导致其他数据类型出现问题。
  • 否 ..取决于您的配置以及您在 API 中的处理方式 .. 尝试使用 ASP.Net 核心默认行为或 WebAPI ..
  • 我不使用.Net,答案也不应该特定于.Net。我正在寻找与语言和框架无关的答案;某种网络标准。
  • 如果我们根本不发送密钥会怎样......那么它会是NULL吗?
  • @tugend 同意.. null 应该/可以通过不发送参数来表示。这仅取决于您如何构建 API。如果您按索引或顺序读取值,那么当然您必须传递一个显式参数。但同样,首选方法应该是在 API 中按参数名称读取值:)
【解决方案3】:

edit 之后更清楚的用例中,我肯定会选择 ?_json= 参数,它没有任何问题,因为在你写的时候一切都适用于 POST,所以没有怀疑这比通过请求参数(application/x-www-form-urlencoded)发明通用绑定协议更好。我个人一直在使用两个参数来支持 XML 等其他内容类型,一个 $rqc 携带像您的 _json 这样的内容,一个 $rqct 携带内容类型,例如:application/json

也就是说,我认为 JSON 效果很好,因为它允许字符串属性有 4 种可能性:

  1. 填写{"param":"foo"}
  2. {"param":""}
  3. 缺席{}
  4. {"param":null}

一个请求参数只能有3个:

  1. 填写?param=foo
  2. ?param=?param(服务器 API 通常不区分这两种情况)
  3. 缺席?

第 4 种可能性,显式 null,可以方便地进行部分更新:如果仅更新请求 JSON 对象中存在的字段;你不能用请求参数轻易地表达出来。

但是,如果您不进行部分更新,您可能会将缺少的参数视为空值,但您需要知道该端点允许的所有参数,如果没有架构或其他规范(一个类绑定到);因为您说您将参数与您可能拥有的类型相关联。

ASP.NET(我现在从答案中了解到)不区分空参数和不存在参数这一事实提醒我,允许空字符串和/或将其与不存在/空字符串区别对待通常是危险的,例如,因为对于 Oracle,一个空字符串被转换为 null,因此对于 NOTNULL 列无效(在 mysql 中是可以的),请参阅null vs empty string in Oracle

因此,如果您不需要支持空字符串和 null/absent 字符串之间的区别,您也可以将空参数视为 null。

如果您想使用请求参数重新创建 JSON {"param":null} 的第 4 点,则必须使用约定,例如按照答案中的建议传递 %00 或使用 null 标记参数 I稍后提出。

如果目的是创建通用的东西,我不会使用%00,因为某些服务器可能启用了一些参数清理机制:如果它拒绝%00(它可能应该这样做)然后公约行不通。我现在检查了一下,JSOUP 删除了%00-%0F 范围内的所有内容。可能 ASP.net 默认也会这样做,请参阅Special character causes "A potentially dangerous Request.Form value"

一种更类似于 HTML 的方法可能是使用额外的 null 标记参数,其名称由带有后缀的原始参数获取,例如:从 param 可以是 param$null:如果参数存在则绑定值为空,无论param 的值是多少,这就像在文本输入之前放置一个 unset 复选框并在选中时取消设置绑定值。此外,如果您有某种方法来注释参数/属性以支持此语法,您可能会将检查限制为这些参数(可能小于总数的 1%),并且对于所有其他参数,以相同的方式处理空参数和不存在参数:绑定将其设置为空值。

【讨论】:

  • %00 如果单独使用,则应仅考虑 null。如果它是较大字符串的一部分,则应正常解码该字符串。这样,就不会有被拒绝或截断的风险。
  • 是的,如果你控制环境,我扩展了答案以澄清我的意思。
【解决方案4】:

使用 IIS 和 C#,我这样发送:

?param=#

【讨论】:

    猜你喜欢
    • 2014-04-09
    • 1970-01-01
    • 2012-05-12
    • 2016-08-25
    • 1970-01-01
    • 2012-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多