Rest 带有URL查询参数的HTTP POST——好主意还是坏主意?
我正在设计一个通过HTTP的API,我想知道使用HTTPPOST命令,但只使用URL查询参数而不使用请求体,是否是一个好方法 考虑事项:Rest 带有URL查询参数的HTTP POST——好主意还是坏主意?,rest,http,Rest,Http,我正在设计一个通过HTTP的API,我想知道使用HTTPPOST命令,但只使用URL查询参数而不使用请求体,是否是一个好方法 考虑事项: “良好的Web设计”要求通过POST发送非幂等操作。这是一个非幂等作用 当URL中存在请求参数时,开发和调试此应用程序更容易 API不打算广泛使用 似乎在没有正文的情况下发出POST请求需要更多的工作,例如必须显式添加内容长度:0标题 在我看来,一篇没有正文的帖子似乎有点违背了大多数开发人员和HTTP框架的期望 通过URL查询而不是请求体发送POST请求的
- “良好的Web设计”要求通过POST发送非幂等操作。这是一个非幂等作用
- 当URL中存在请求参数时,开发和调试此应用程序更容易
- API不打算广泛使用
- 似乎在没有正文的情况下发出POST请求需要更多的工作,例如必须显式添加
标题内容长度:0
- 在我看来,一篇没有正文的帖子似乎有点违背了大多数开发人员和HTTP框架的期望
从编程的角度来看,对于客户端来说,它打包参数并将它们附加到url上,并执行POST和GET。在服务器端,它从querystring而不是从发布的字节计算入站参数。基本上,这是一个清洗 优势/劣势可能在于特定的客户端平台如何在其网络堆栈中使用POST和GET例程,以及web服务器如何处理这些请求。根据您的实现,一种方法可能比另一种更有效。知道这一点将指导你在这里的决定
尽管如此,从程序员的角度来看,我更喜欢允许在正文中包含所有参数的POST,或者在url上包含所有参数的GET,并在任何POST请求中显式忽略url参数。它避免了混淆。我同意-如果只是在URL而不是正文中传递数据,那么使用GET请求可能更安全。有关整个POST+GET概念的更多视图,请参阅。您想知道原因吗?这里有一个: web表单不能用于向混合使用GET和POST的页面发送请求。如果将表单的方法设置为GET,则所有参数都在查询字符串中。如果将表单的方法设置为POST,则所有参数都在请求正文中
来源:HTML4.01标准,第节如果您的操作不是幂等的,则必须使用
POST
。如果你不这样做,那你就是自找麻烦GET
、PUT
和DELETE
方法必须是幂等的。想象一下,如果客户端预取了所有可能的GET
服务请求,应用程序中会发生什么情况?如果这会导致客户端可见的副作用,那么一定是出了问题
我同意发送带有查询字符串但没有正文的POST
似乎有些奇怪,但我认为它在某些情况下是合适的
将URL的查询部分视为对资源的命令,以限制当前请求的范围。通常,查询字符串用于对GET
请求进行排序或过滤(如?page=1&sort=title
),但我认为在帖子上限制范围(可能像?action=delete&id=5
)也是有意义的。该阵营有一些指导原则,我们可以用来标准化我们使用HTTP动词的方式。这在构建RESTful API时非常有用
简言之:
GET应该是只读的,即对服务器状态没有影响。
POST用于在服务器上创建资源。
PUT用于更新或创建资源。
删除用于删除资源
换句话说,如果您的API操作更改了服务器状态,REST建议我们使用POST/PUT/DELETE,而不是GET
用户代理通常明白,多发帖子是不好的,并且会发出警告,因为帖子的目的是改变服务器状态(例如,在结账时付款),而您可能不想再发两次
与一个你想做什么就做什么的GET(幂等)相比,每个人都是对的:对于非幂等请求,请坚持使用POST
使用URI查询字符串和请求内容如何?它是有效的HTTP(见注1),为什么不呢
这也是完全合乎逻辑的:URL,包括它们的查询字符串部分,用于定位资源。而HTTP方法动词(POST及其可选的请求内容)用于指定操作或如何处理资源。这些应该是相互关联的问题。(但是,对于ContentType=application/x-www-form-urlencoded的特殊情况,它们并不是最佳的正交关系,请参见下面的注释2。)
注1:HTTP规范(1.1)没有说明对于接受POST或PUT请求的HTTP服务器,查询参数和内容是互斥的。因此,任何服务器都可以自由地接受这两种服务。也就是说,如果您编写服务器,那么没有什么可以阻止您选择同时接受这两种方式(除了一个不灵活的框架)。通常,服务器可以根据它使用的任何规则解释查询字符串
POST /user_settings?user_id=4
{
"use_safe_mode": 1
}
POST /user_settings/4
{
...
}
POST /user_settings/{user_id}/{which_settings_id}/{xyz}/{abc}/ ...
{
...
}