这个问题不是关于什么时候使用GET或POST;这是关于哪一个是建议处理注销web应用程序。我已经找到了大量关于GET和POST之间一般意义上的区别的信息,但是我没有找到针对这个特定场景的明确答案。

作为一个实用主义者,我倾向于使用GET,因为实现它比POST简单得多;只需删除一个简单的链接,就完成了。这似乎是我能想到的绝大多数网站的情况,至少从我的头脑。甚至Stack Overflow也可以使用GET处理注销。

The thing making me hesitate is the (albeit old) argument that some web accelerators/proxies pre-cache pages by going and retrieving every link they find in the page, so the user gets a faster response when she clicks on them. I'm not sure if this still applies, but if this was the case, then in theory a user with one of these accelerators would get kicked out of the application as soon as she logs in, because her accelerator would find and retrieve the logout link even if she never clicked on it.

到目前为止,我所读到的所有内容都表明POST应该用于“破坏性操作”,而不改变应用程序内部状态的操作(如查询等)应该使用GET处理。基于此,真正的问题是:

注销应用程序是否被认为是破坏性操作/是否会改变应用程序的内部状态?


好吧,如果你让你的web应用程序通过注销脚本放弃会话,你通常不需要这些。通常情况下,对于您想要放弃的会话,有一个惟一的会话变量。

正确地说,GET/POST(或其他动词)是对某些资源(通过URL寻址)的操作——因此它通常是关于资源的状态,而不是关于应用程序的状态。因此,在真正的精神,您应该有一个URL,如[主机名]\[用户名]\session,然后'DELETE'将是注销操作的正确动词。

使用[主机名]\bla bla\logout作为URL并不是真正的REST完全方式(IMO),所以为什么要争论正确使用GET/POST呢?

当然,我也使用GET注销url在我的应用程序:-)

预缓存的场景是一个有趣的场景。但我猜,如果很多网站inc . SO不用担心这个,那么也许你也不应该担心。

或者这个链接可以用javascript实现?

编辑:根据我的理解,从技术上讲,GET应该用于不改变应用程序状态的只读请求。POST应该用于改变状态的写/编辑请求。然而,对于某些状态更改请求,其他应用程序问题可能更倾向于GET而不是POST,我不认为这有任何问题。

Logging out does nothing to the application itself. It changes the user's state in relation to the application. In this case, it appears your question is more based on how should the command be initiated from the user to begin this action. Since this is not a "destructive action", sure the session is abandoned or destroyed but neither your application or your data is altered, it is not infeasible to allow both methods to initiate a log out procedure. The post should be used by any user initiated actions (e.g. - user clicks "Log out"), while get could be reserved for application initiated log outs (e.g. - an exception detecting potential user intrusion forcibly redirects to the login page with a logout GET).

在REST中不应该有会话,因此不需要破坏任何东西。REST客户机对每个请求进行身份验证。登录或退出,都只是幻觉。

您真正要问的是浏览器是否应该在每个请求上继续发送身份验证信息。

可以说,如果您的应用程序确实创建了登录的假象,那么您应该能够使用javascript“注销”。不需要往返。


论文论文-第5.1.3节

从客户端到服务器的每个请求 必须包含所有的信息吗 为了理解请求, 而且不能占任何便宜 服务器上存储的上下文。会话 因此,国家完全处于状态 客户端

GET在这里可能被滥用的一种方式是,有人(可能是竞争对手)在internet上的任何地方放置了一个带有src="<您的注销链接>"的图像标记,如果您站点的用户偶然发现该页面,他将在不知不觉中注销。

我不认为注销(降低用户权限)是一种破坏性的行为。这是因为“注销”操作应该只对已经登录的用户可用,否则它将被淘汰。

浏览器cookie中包含的随机生成的字符串都表示用户会话。有成千上万的方法来破坏它,所以有效地注销只是一个服务你的访问者。

使用POST。

在2010年,使用GET可能是一个可以接受的答案。但在今天(2013年),浏览器会预取它们“认为”你接下来会访问的页面。

下面是StackOverflow的一位开发者在twitter上谈论这个问题:

我要感谢我的银行注销一个GET请求,和Chrome团队方便的URL预取。——尼克·克雷弗(@Nick_Craver) 2013年1月29日

有趣的事实:StackOverflow曾经通过GET处理注销,但不再。

你好,在我看来,当你登录时,你检查用户名/密码,如果它们匹配,你创建登录令牌。

CREATE token =>方法POST

当你注销时,你破坏令牌,所以对我来说,最合乎逻辑的方法应该是DELETE

DELETE令牌=>方法DELETE

根据Mozilla开发者网络web文档锚(<a>)标签没有预取(截至2022年底)。可能还有其他原因不使用锚标记,但根据MDN,由于浏览器预取而意外注销似乎不是一个有效的原因。