带有URL查询参数的HTTP POST – 好主意还是不好?

我正在devise一个API来通过HTTP,我想知道是否使用HTTP POST命令,但只有URL查询参数,没有请求正文,是一个好方法。

注意事项:

  • “良好的网页devise”要求通过POST发送非幂等动作。 这是一个非幂等的行为。
  • 当请求参数存在于URL中时,开发和debugging这个应用程序会更容易。
  • 该API不是为了广泛使用。
  • 看起来像做一个POST请求没有正文将需要更多的工作,例如一个Content-Length: 0头必须显式添加。
  • 在我看来,没有任何内容的POST与大多数开发人员和HTTP框架的期望有点相反。

通过URL查询而不是请求体发送POST请求的参数是否有更多的缺陷或优点?

编辑:这正在考虑的原因是,操作不是幂等的,并有除了检索副作用。 请参阅HTTP规范 :

具体而言,公约已经确定GET和HEAD方法不应该具有除了检索之外采取行动的意义。 这些方法应该被认为是“安全的”。 这允许用户代理以一种特殊的方式表示其他方法,例如POST,PUT和DELETE,以使用户意识到可能不安全的动作被请求的事实。

方法也可以具有“幂等性”的性质(除了错误或过期问题),N> 0个相同请求的副作用与单个请求相同。 方法GET,HEAD,PUT和DELETE共享这个属性。 而且,OPTIONS和TRACE方法不应该有副作用,所以它们本身就是幂等的。

如果你的行为不是幂等的,那么你必须使用POST 。 如果你不这样做,你只是要求排除故障。 GETPUTDELETE方法需要是幂等的。 想象一下,如果客户端预先获取服务的每个可能的GET请求,应用程序中会发生什么情况 – 如果这会导致客户端可见的副作用,那么就会出现问题。

我同意发送一个查询string,但没有一个身体似乎很奇怪,但我认为这可能是适当的在某些情况下。

将URL的查询部分看作是对资源的命令,以限制当前请求的范围。 通常情况下,查询string用于sorting或过滤GET请求(如?page=1&sort=title ),但我想这是有道理的,也限制了范围(可能像?action=delete&id=5 )。

每个人都是正确的:坚持POST非幂等请求。

使用URI查询string和请求内容怎么样? 那么这是有效的HTTP(见注1),所以为什么不!

这也是完全合乎逻辑的:URLs(包括它们的查询string部分)用于查找资源。 HTTP方法动词(POST – 及其可选的请求内容)用于指定动作,或者如何处理资源。 这些应该是正交的担忧。 (但是,对于ContentType = application / x-www-form-urlencoded的特殊情况,它们并不是完美的正交关系,请参阅下面的注2。

注1:HTTP规范(1.1)没有规定查询参数和内容对于接受POST或PUT请求的HTTP服务器是互斥的。 所以任何服务器都可以自由接受这两个。 也就是说,如果你写服务器,没有什么可以阻止你select接受这两者(除了可能是一个僵化的框架)。 通常,服务器可以根据需要的任何规则来解释查询string。 它甚至可以用引用其他头部的条件逻辑来解释它们,比如Content-Type,这导致了注2:

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

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

如果读者提出这个问题,想要问什么是好的RESTful体系结构:RESTful体系结构模式不需要URIscheme来工作的具体方式。 RESTful体系结构与系统的其他属性有关,如资源的caching能力,资源本身的devise(他们的行为,能力和表示)以及是否满足幂等性。 或者换句话说,实现一个与HTTP协议及其HTTP方法动词集高度兼容的devise。 (换句话说,RESTful体系结构对于资源的定位并不是非常重要)。

最后一点:有时查询参数会被用于其他的事情,既不是定位资源也不是编码内容。 曾经见过像“PUT = true”或“POST = true”的查询参数? 这些是不允许您使用PUT和POST方法的浏览器的解决方法。 虽然这样的参数被视为URL查询string的一部分,但我认为它们并不是URL中查询的一部分。

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

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

来源:HTML 4.01标准,第17.13节表单提交

从编程的angular度来看,对于客户端来说,它打包了一些参数,然后把它们附加到url上,然后进行POST和GET。 在服务器端,它正在查询来自查询string的入站参数,而不是发布的字节。 基本上,这是一个洗。

哪里可能有优势/劣势可能在于特定客户端平台如何在其networking堆栈中使用POST和GET例程,以及Web服务器如何处理这些请求。 根据您的实施情况,一种方法可能比另一种更有效。 知道这将指导你的决定。

尽pipe如此,从程序员的angular度来看,我更愿意允许在主体中包含所有参数的POST,或者在url上包含所有参数的GET,并且明确地忽略任何POST请求的url参数。 它避免了混淆。

我认为它仍然是相当RESTful有查询参数标识URL上的资源,同时保持内容有效载荷限于POST正文。 这似乎分开了“我送什么”的考虑。 与“我是谁发送给?”。

REST阵营有一些指导原则,我们可以用它来标准化我们使用HTTP动词的方式。 在您构buildRESTful API时,这很有帮助。

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

换句话说,如果你的API动作改变了服务器状态,RESTbuild议我们使用POST / PUT / DELETE,而不是GET。

用户代理通常会理解,执行多个POST是不好的,并会警告它,因为POST的目的是改变服务器状态(例如,在结帐时支付货款),而且你可能不想这样做两次!

比较一个你可以经常使用的GET(幂等)。

我同意 – 如果您只是在URL中传递数据而不在本体中,那么使用GET请求可能更安全。 关于整个POST + GET概念的一些额外的观点,请看这个类似的问题 。