代码之家  ›  专栏  ›  技术社区  ›  Steven Huwig

带URL查询参数的HTTP POST-好主意还是不好?[关闭]

  •  387
  • Steven Huwig  · 技术社区  · 16 年前

    我正在设计一个通过HTTP的API,我想知道使用HTTPPOST命令,但只使用URL查询参数,而不使用请求体,是否是一种好的方法。

    考虑事项:

    • “良好的网页设计”要求通过邮件发送非等幂操作。这是一个非等幂运算。
    • 当请求参数存在于URL中时,开发和调试此应用程序更容易。
    • API并不打算广泛使用。
    • 似乎在没有人的情况下提出一个帖子请求需要更多的工作,例如 Content-Length: 0 必须显式添加头。
    • 在我看来,一篇没有正文的文章有点违背了大多数开发人员和HTTP框架的期望。

    通过URL查询而不是请求主体发送POST请求的参数是否还有其他的陷阱或优势?

    编辑:正在考虑的原因是这些操作不是等幂的,除了检索之外还有其他副作用。见 the HTTP spec :

    特别是,公约 确定了GET和HEAD 方法不应具有 采取其他行动的意义 而不是检索。这些方法应该 被认为是“安全的”。这允许用户 代理其他方法, 例如,在 特殊的方式,使用户 意识到一个事实 正在请求不安全的操作。

    方法还可以具有 其中的“等幂”(除 错误或过期问题) n>0的副作用相同 请求与单个请求相同 请求。方法有,有,有,有 删除共享此属性。也, 方法选项和跟踪应该 没有副作用,也没有副作用 本质上是等幂的。

    7 回复  |  直到 6 年前
        1
  •  208
  •   Don McCaughey    16 年前

    如果你的行为不是等幂的,那么你 必须 使用 POST . 如果你不这样做,你就是在自找麻烦。 GET , PUT DELETE 方法是 必修的 是等幂的。想象一下,如果客户端尽可能地预取数据,应用程序中会发生什么情况 得到 请求您的服务——如果这会导致客户端可见的副作用,那么就有问题了。

    我同意发送 使用查询字符串但不使用主体似乎很奇怪,但我认为在某些情况下它是合适的。

    把URL的查询部分看作资源的命令,以限制当前请求的范围。通常,查询字符串用于排序或筛选 得到 请求(如 ?page=1&sort=title )但我想这是有道理的 也限制范围(可能是 ?action=delete&id=5 )

        2
  •  107
  •   Tim Lovell-Smith    8 年前

    每个人都是对的:对于非等幂请求,坚持使用post。

    如何同时使用URI查询字符串和请求内容?它是有效的HTTP(见注1),为什么不呢?

    这也是完全合乎逻辑的:URL(包括其查询字符串部分)用于 定位 资源。而HTTP方法动词(post-及其可选请求内容)用于指定操作,或者 怎么办 资源。这些应该是正交关系。(但是,对于contentType=application/x-www-form-urlencoded的特殊情况,它们并非完美的正交关系,请参见下面的注释2。)

    注1:HTTP规范(1.1)没有说明接受POST或PUT请求的HTTP服务器的查询参数和内容是互斥的。所以任何服务器都可以自由地接受这两种情况。也就是说,如果您编写服务器,没有什么可以阻止您选择同时接受这两个(可能是不灵活的框架除外)。通常,服务器可以根据需要的规则解释查询字符串。它甚至可以用条件逻辑来解释它们,条件逻辑也引用其他头,比如内容类型,这导致了注2:

    注2:如果A 网络浏览器 是人们访问您的Web应用程序的主要方式,以及 应用程序/X-WWW-FORM-URLENCODED 是他们发布的内容类型,然后是您 应该 遵循该内容类型的规则。application/x-www-form-urlencoded的规则更为具体(坦率地说,不常见):在这种情况下,必须将URI解释为一组参数,而不是资源位置。[这与PowerLord提出的有用性观点相同,即使用Web表单向您的服务器发布内容可能很困难。只是解释得有点不同。]

    注3:查询字符串的最初用途是什么?RFC3986将HTTP查询字符串定义为一个URI部分,该部分作为查找资源的非分层方式工作。

    如果读者问这个问题,希望问什么是好的RESTful体系结构:RESTful体系结构模式不需要URI方案以特定方式工作。RESTful体系结构本身与系统的其他属性有关,例如资源的可缓存性、资源本身的设计(它们的行为、功能和表示)以及是否满足等幂性。或者换句话说,实现与HTTP协议及其一组HTTP方法动词高度兼容的设计。:-)(换句话说,RESTful架构对资源的定义不是很有前提 位于 )

    最后一点注意:有时查询参数还用于其他事情,这些事情既不是定位资源,也不是编码内容。有没有见过像'Put=true'或'Post=true'这样的查询参数?对于不允许使用Put和Post方法的浏览器,这些是解决方法。虽然这些参数被视为URL查询字符串的一部分(在线上),但我认为它们不是URL查询的一部分。 在精神上 .

        3
  •  60
  •   Powerlord    16 年前

    你想要理由吗?这里有一个:

    Web表单不能用于将请求发送到使用get和post组合的页面。如果将窗体的方法设置为get,则所有参数都在查询字符串中。如果将窗体的方法设置为Post,则所有参数都在请求主体中。

    来源:HTML 4.01标准,章节 17.13 Form Submission

        4
  •  8
  •   jro    16 年前

    从编程的角度来看,对于客户机来说,它打包参数并将它们附加到URL上,然后执行post与get。在服务器端,它正在从查询字符串而不是发布的字节评估入站参数。基本上,这是一次洗漱。

    其中可能存在的优点/缺点可能是特定的客户机平台如何处理POST,在其网络堆栈中获取例程,以及Web服务器如何处理这些请求。根据您的实现,一种方法可能比另一种方法更有效。知道这将指导你的决定。

    然而,从程序员的角度来看,我更喜欢允许一个包含正文中所有参数的post,或者一个包含URL上所有参数的get,并且在任何post请求中显式地忽略url参数。它避免了混乱。

        5
  •  4
  •   swizzcheez    13 年前

    我认为,在将内容有效负载限制在post主体上的同时,使用查询参数来标识URL上的资源,仍然是相当安全的。这似乎将“我要发送什么”的考虑分开了。与“我将它发送给谁?”.

        6
  •  1
  •   saille    13 年前

    这个 REST camp有一些指导原则,我们可以使用这些原则来规范我们使用HTTP动词的方式。这在像您所做的那样构建RESTfulAPI时很有用。

    简而言之: get应该是只读的,即对服务器状态没有影响。 post用于在服务器上创建资源。 Put用于更新或创建资源。 删除用于删除资源。

    换句话说,如果您的API操作更改了服务器状态,REST建议我们使用post/put/delete,但不要使用get。

    用户代理通常理解做多个帖子是不好的,并且会对此发出警告,因为发布的目的是改变服务器状态(例如,在结账时支付商品费用),而您可能不想这样做两次!

    比较一个你可以经常做你喜欢的得到(等幂)。

        7
  •  -12
  •   Community CDub    8 年前

    我同意-如果您只是在URL中而不是在正文中传递数据,那么使用GET请求可能更安全。见 this similar question 对于整个post+get概念的一些附加视图。