首页 文章

带有URL查询参数的HTTP POST - 好主意与否? [关闭]

提问于
浏览
380

我正在设计一个API以通过HTTP,我想知道是否使用HTTP POST命令,但只使用URL查询参数而没有请求体,是一个很好的方法 .

注意事项:

  • "Good Web design"要求通过POST发送非幂等操作 . 这是一种非幂等行为 .

  • 当URL中存在请求参数时,更容易开发和调试此应用程序 .

  • 该API不适合广泛使用 .

  • 似乎在没有正文的情况下发出POST请求会花费更多的工作,例如必须明确添加 Content-Length: 0 标头 .

  • 在我看来,没有正文的POST与大多数开发人员的预期有点相反 .

通过URL查询而不是请求正文在POST请求上发送参数是否还有其他缺陷或优势?

编辑:正在考虑的原因是操作不是幂等的,并且除了检索之外还有副作用 . 见the HTTP spec

特别是,已经确定了GET和HEAD方法不具有采取除检索之外的动作的重要性的约定 . 这些方法应该被认为是“安全的” . 这允许用户代理以特殊方式表示其他方法,例如POST,PUT和DELETE,以便使用户意识到正在请求可能不安全的操作 . ...方法也可以具有“幂等”的属性(除了错误或过期问题)N> 0个相同请求的副作用与单个请求相同 . 方法GET,HEAD,PUT和DELETE共享此属性 . 此外,方法OPTIONS和TRACE不应该有副作用,因此本质上是幂等的 .

7 回答

  • -12

    REST阵营有一些指导原则,我们可以用来标准化我们使用HTTP动词的方式 . 这在构建RESTful API时非常有用 .

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

    换句话说,如果您的API操作更改了服务器状态,REST建议我们使用POST / PUT / DELETE,而不是GET .

    用户代理通常理解执行多个POST是不好的并且会警告它,因为POST的意图是改变服务器状态(例如,在结账时支付货物),并且您可能不希望这样做两次!

    比较你可以随意做的GET(幂等) .

  • 4

    我认为在保持内容有效负载限制在POST主体的同时,拥有标识URL上资源的查询参数仍然可能非常RESTful . 这似乎将“我要发送什么?”的考虑因素分开 . 与“我是谁将它发送给谁?” .

  • 60

    每个人都是对的:坚持使用POST来处理非幂等请求 .

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

    它也是完全合乎逻辑的:URL(包括其查询字符串部分)用于查找资源 . 而HTTP方法谓词(POST - 及其可选的请求内容)用于指定操作或如何处理资源 . 那些应该是正交问题 . (但是,对于ContentType = application / x-www-form-urlencoded的特殊情况,它们并不是完美正交的问题,请参阅下面的注释2 . )

    注1:HTTP规范(1.1)没有声明查询参数和内容对接受POST或PUT请求的HTTP服务器是互斥的 . 所以任何服务器都可以自由接受 . 即如果你写服务器那么没有什么可以阻止你选择接受两者(除了可能是一个不灵活的框架) . 通常,服务器可以根据它想要的任何规则来解释查询字符串 . 它甚至可以用引用其他 Headers 的条件逻辑来解释它们,例如Content-Type,这导致注2:

    注意2:如果Web浏览器是人们访问Web应用程序的主要方式,并且 application/x-www-form-urlencoded 是他们发布的Content-Type,那么您应该遵循该Content-Type的规则 . application / x-www-form-urlencoded的规则更加具体(坦率地说,不常见):在这种情况下,您必须将URI解释为一组参数,而不是资源位置 . [这与Powerlord提出的有用点相同;可能很难使用Web表单将内容POST到您的服务器 . 刚才解释得有点不同 . ]

    注3:最初的查询字符串是什么? RFC 3986将HTTP查询字符串定义为URI部分,作为定位资源的非分层方式 .

    如果读者提出这个问题希望问什么是好的RESTful架构:RESTful架构模式不需要URI方案以特定的方式工作 . RESTful架构关注系统的其他属性,如资源的可缓存性,资源的设计他们自己(他们的行为,能力和表现),以及是否满足幂等性 . 或者换句话说,实现与HTTP协议及其HTTP方法动词集高度兼容的设计 . :-)(换句话说,RESTful架构对资源的定位方式并不十分明确 . )

    最后的注意事项:有时候查询参数会被用于其他东西,既不是资源的定位,也不是编码内容 . 曾经见过像'PUT=true'或'POST=true'这样的查询参数?这些是浏览器的解决方法,它们在精神上不需要查询 .

  • 106

    你想要理由吗?这是一个:

    Web表单不能用于向使用GET和POST混合的页面发送请求 . 如果将表单的方法设置为GET,则所有参数都在查询字符串中 . 如果将表单的方法设置为POST,则所有参数都在请求正文中 .

    来源:HTML 4.01标准,第17.13 Form Submission

  • 1

    从程序化的角度来看,对于客户端来说,它打包参数并将它们附加到URL并进行POST与GET . 在服务器端,它正在从查询字符串而不是发布的字节中评估入站参数 . 基本上,这是一个洗 .

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

    尽管如此,从程序员的角度来看,我更喜欢允许在主体中使用所有参数的POST,或者在URL上使用所有参数的GET,并使用任何POST请求显式忽略url参数 . 它避免了混乱 .

  • 8

    我同意 - 它只是在URL中而不是在正文中传递数据 . 有关整个POST GET概念的一些其他视图,请参阅this similar question .

  • 203

    如果你的行为不是幂等的,那么你必须使用 POST . 如果你只是要求排除故障 . GETPUTDELETE 方法必须是幂等的 . 想象一下,如果客户端预先为您的服务预先提取所有 GET 请求,您的应用程序会发生什么 - 如果这会导致客户端看到副作用,那么就会出错 .

    我同意发送带有查询字符串但没有正文的 POST 似乎很奇怪,但我认为在某些情况下这是合适的 .

    可以将URL的查询部分视为资源的命令,以限制当前请求的范围 . 通常,查询字符串用于排序或过滤 GET 请求(如 ?page=1&sort=title ),但我认为在 POST 上也有意义也限制范围(可能像 ?action=delete&id=5 ) .

相关问题