什么时候使用POST?什么时候使用GET?


342

据我所知,共有三类:

  1. 永远不要使用GET和使用POST
  2. 永远不要使用POST和使用GET
  3. 不管使用哪个。

我认为这三种情况正确吗?如果是这样,每种情况下有哪些示例?


1
这实际上是绝对不正确的。GET和POST都在同一程度上可见,如果您查看浏览器发送的标头,则会看到您发布的键值对的列表
Velimir Tchatchevsky


1
没有标准的方法可以将多个名称->值对编码成查询字符串,因此,除非您的请求是非常基本的(即没有数组或嵌套的数据结构),否则您应该考虑仅使用POST,该POST提供可用于编码格式的主体字段(JSON,XML等)。
themihai

Answers:


376

使用POST破坏性行动,如创建(我知道的讽刺),编辑和删除,因为你不能打了一个POST在浏览器的地址栏中行动。使用GET时,它是安全的,让一个人打电话的动作。像这样的URL:

http://myblog.org/admin/posts/delete/357

应该带您到确认页面,而不是简单地删除项目。这样避免事故要容易得多。

POST还比更加安全GET,因为您没有将信息粘贴到URL中。因此,最好不要将HTML表单GET用作method收集密码或其他敏感信息的HTML表单。

最后一点:比POST可以传输更多的信息GET。“ POST”对传输的数据没有大小限制,而“ GET”限制为2048个字符。


82
可能会获取对GET请求的响应。对POST的响应一定不能。
mkoeller

31
如何将信息粘贴在URL中如何使其更安全?(顺便说一句,我是那些认为错误的安全感比根本没有安全感更危险的人之一)。
ePharaoh

42
@ePharaoh:通过在地址栏上看着用户的肩膀来阻止人们读取密码。
昆汀2009年

34
@ePharaoh:“向偶然的观察者提供较少的数据”可能比“更加安全的”提供更好的表述-URL可能以很多地方结尾,例如日志,引用,缓存。您当然是正确的,这不会增加安全性-但它限制了最糟糕的不安全做法(另请参见:thedailywtf.com/Articles/The_Spider_of_Doom.aspx
Piskvor在2009年

24
@戴维·多沃德(David Dorward):或者用更通用的名字:肩膀攻击
伊丹·K

206

简单来说

  • 使用GETsafe andidempotent请求
  • 使用POSTneither safe nor idempotent请求

详细信息 每个都有一个适当的位置。即使您不遵循RESTful原则,也可以通过了解REST以及面向资源的方法如何工作而获得很多好处。

RESTful应用程序将use GETs同时执行这两种操作safe and idempotent

一个safe操作是超出的操作not change the data要求。

一项idempotent操作是一种结果,be the same无论您请求多少次,结果都将如此。

有理由认为,由于GET用于安全操作,因此它们也自动成为幂等的。通常,GET用于检索资源(例如,关于堆栈溢出的问题及其相关答案)或资源集合。

RESTful应用程序将PUTs用于not safe but idempotent

我知道问题是关于GET和POST的,但是我稍后将返回POST。

通常,PUT用于编辑资源(例如,在堆栈溢出时编辑问题或答案)。

A POST将用于的任何操作neither safe or idempotent

通常,POST将用于创建新资源,例如,创建NEW SO问题(尽管在某些设计中,PUT也将用于此)。

如果您两次运行POST,最终将创建两个新问题。

还有一个DELETE操作,但是我想我可以把它留在这里了:)

讨论区

实际上,现代Web浏览器通常仅可靠地支持GET和POST(您可以通过javascript调用执行所有这些操作,但是就以表格形式输入数据并按Submit而言,通常会有两种选择)。在RESTful应用程序中,POST通常会被覆盖以提供PUT和DELETE调用。

但是,即使您没有遵循RESTful原则,也可以考虑使用GET来检索/查看信息,以及使用POST来创建/编辑信息。

绝对不要将GET用于更改数据的操作。如果搜索引擎抓取到您的恶意操作的链接,或者客户添加了书签,则可能会带来很大的麻烦。


如果您要创建用于登录的APIREST资源(可以选择),那么这是安全的并且是幂等的,我对此进行了说明。
jhonny lopez

1
安全获取并非自动幂等。对于相同的无损查询,结果集可能会有所不同。
RichieHH

1
您编写它的方式是“ GET currenttime”之类的错误,因为它不是幂等的(从某种意义上说,重复查询可能会产生不同的结果);实际上,所查询的任何内容都可能随时间变化。因此,应该根据查询本身的副作用来表达幂等性由于只要求提供当前时间没有副作用,因此-正如人们可能期望的那样-这是GET而不是POST的理想选择。
哈根·冯·埃岑

79

如果您不介意重复请求(即不更改状态),请使用GET。

如果操作确实更改了系统状态,请使用POST。


1
由于表单会更改系统状态,因此为什么HTML表单标签的默认方法是GET?
ziiweb 2011年

3
@ user248959搜索框是否更改可见状态?默认设置是很久以前设置的,可能几乎是偶然的。我还没有深入研究历史,甚至还不知道POST是否是一个选项。
道格拉斯·里德

@ziiweb即使<form>的大多数用例是POST,也最好将dafault定义为“无害” GET。从安全的角度看,这可能会导致日志文件等中暴露的数据,这似乎是荒谬的,但是对于服务器端数据,它是故障安全的(服务不应在GET上修改数据)。我想,今天的焦点会有所不同(最好是删除任何默认值并method强制执行)
Hagen von Eitzen

假设我有一个接受文件作为输入的端点,对该文件进行了一些处理(例如,基于正则表达式提取数据)并返回JSON数据,然后可以使用GET请求将文件上传到服务器。还是应该使用POST请求?
变量

67

简洁版本

GET:通常用于提交的搜索请求或您希望用户能够再次拉出确切页面的任何请求。

GET的优点:

  • 可以安全地为URL添加书签。
  • 页面可以安全地重新加载。

GET的缺点:

POST:用于更高安全性的请求,其中可能使用数据来更改数据库或您不希望某人添加书签的页面。

POST的优点:

  • 名称/值对不显示在url中。(安全性+ = 1)
  • 可以通过POST传递无限数量的名称/值对。参考。

POST的缺点:

  • 使用POST数据的页面不能作为书签。(如果您愿意)。

较长的版本

直接来自超文本传输​​协议-HTTP / 1.1

9.3获取

GET方法意味着检索由Request-URI标识的任何信息(以实体形式)。如果Request-URI涉及数据产生过程,则应将产生的数据作为响应中的实体而不是过程的源文本作为实体返回,除非该文本恰好是过程的输出。

如果请求消息包含If-Modified-Since,If-Unmodified-Since,If-Match,If-None-Match或If-Range头字段,则GET方法的语义将变为“条件GET”。条件GET方法仅在条件标头字段描述的情况下才请求转移实体。有条件的GET方法旨在通过允许刷新缓存的实体而无需多个请求或传输客户端已经拥有的数据来减少不必要的网络使用。

如果请求消息包含Range标头字段,则GET方法的语义将更改为“部分GET”。如第14.35节所述,部分GET请求仅转移实体的一部分。部分GET方法旨在通过允许部分取回的实体完成而无需传输客户端已经拥有的数据来减少不必要的网络使用。

且仅当满足GET请求的响应符合第13节中描述的HTTP缓存要求时,该响应才可以缓存。

有关用于表单的安全性注意事项,请参见15.1.3节。

9.5开机自检

POST方法用于请求源服务器接受请求中包含的实体作为请求行中Request-URI标识的资源的新下属。POST旨在允许采用统一的方法来覆盖以下功能:

  • 注释现有资源;

  • 将消息发布到公告板,新闻组,邮件列表或类似的文章组;

  • 向数据处理过程提供数据块,例如提交表单的结果;

  • 通过附加操作扩展数据库。

POST方法执行的实际功能由服务器确定,通常取决于Request-URI。发布的实体从属于该URI,其方式与文件从属于包含该实体的目录,新闻文章从属于其发布到的新闻组或记录从属于数据库的方式相同。

POST方法执行的操作可能不会导致可以由URI标识的资源。在这种情况下,适当的响应状态是200(确定)或204(无内容),这取决于响应是否包括描述结果的实体。


2
“使用帖子数据的页面无法添加书签”:好吧,这是一个优势,不是吗?您可能不希望将您的数据更改查询添加为书签。
Piskvor于

我想如果每次使用帖子都是出于安全性目的使用它,那么这将是一个优势。通常是这样,但是GET上有长度限制。也许有人只是传递了大量与安全无关的数据,并希望该页面被添加书签?谁知道...
Cimplicity

关于GET的缺点,即“变量通过url作为名称-值对进行粘贴”,由于路由和生成的友好URL,MVC是否可以消除该问题?
MrBoJangles 2011年

@MrBoJangles:使用漂亮的URL不会阻止提到的“抬头看人”的风险。旁注:MVC不需要使用漂亮的URL进行路由,而使用漂亮的URL的路由则不需要MVC。它们有时可以一起使用,也可以分开使用。
icktoofay 2012年

在.NET世界中,出于所有实际目的,好的url功能= MVC。我想您可以进行一些IIS重写或一些基于代码的怪异的重写,但它们甚至不那么令人愉快。毫无疑问,MVC赢得了胜利。
MrBoJangles 2012年

28

首先重要的是GET vs POST 的含义

  • GET应该用于... 服务器获取一些信息,
  • 而POST应该被用来发送一些信息服务器。


之后,需要注意几件事:

  • 使用GET,您的用户可以使用其浏览器中的“后退”按钮,并且可以为页面添加书签
  • 可以作为GET传递的参数的大小有限制(某些版本的Internet Explorer,如果没有记错的话,为2KB);POST的限制更大,并且通常取决于服务器的配置。


无论如何,如果没有GET,我认为我们无法“生存”:考虑每天使用多少个带有查询字符串中参数的URL -如果没有GET,所有这些URL将无法使用;-)


好吧,如果每个人都以GET方式使用漂亮的网址:http://example.com/var1/value1/var2/value2/var3/value3我们可能在技术上不再拥有GET ...
Tyler Carter 2010年

5
@ Chacha102除了您仍然必须获取该资源。几乎所有页面,图像,脚本等都使用GET加载到Web浏览器中。
瑞安

3
@ Chacha102-甚至www.mypage.com/contact/内部使用GET之类的东西index.php?url=/contact/
Thiago Belem 2010年

1
强调GET的大小限制!另外,GET参数包含在书签中,而POST不包含。并且,用户可以刷新GET请求的页面,但不能刷新POST请求的页面(没有有关重新发送信息的警告)。
Ricket 2010年

12

除了在许多Web浏览器中的长度约束差异之外,还存在语义差异。GET被认为是“安全的”,因为它们是只读操作,不会更改服务器状态。POST通常会更改状态,并会在重新提交时发出警告。搜索引擎的网络爬虫可能会执行GET,但绝不应进行POST。

如果要读取数据而不更改状态,请使用GET;如果要更新服务器上的状态,请使用POST。


+1。这是与其他一切所依据的rfc的关键概念差异。w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3
Frank Farmer 2010年

8

我的一般经验法则是在向服务器发出不会更改状态的请求时使用Get。保留帖子以供更改状态的服务器请求。


8

一个实际的区别是浏览器和Web服务器对URL中可以存在的字符数有限制。每种应用程序的应用程序都不同,但是如果textarea您使用表单,肯定有可能将其击中。

另一个与GET有关的陷阱-它们被搜索引擎和其他自动系统索引。Google曾经有一种产品可以在您正在查看的页面上预提取链接,因此,如果您单击这些链接,它们的加载速度会更快。它对具有链接之类的网站造成了严重破坏delete.php?id=1-人们失去了整个网站。


1
您的网络服务器可能对此也有限制。
Billy ONeal

好吧,POST也有限制。
chelmertz

1
好的,@ BillyONeal,我已经添加了。@chelmertz是的,但是我可以根据需要更改它,它要高得多。例如,我已将1 GB的文件发布到Apache实例。
ceejayoz

我了解网址已被搜索引擎编入索引。我不知道这与GET有什么关系。我的意思是URL不仅仅是URL吗?
蜂蜜

1
@Honey搜索引擎遵循链接。链接发出GET请求。搜索引擎不会提交表单(如果提交的话,您会看到Google每隔几天在您的网站上注册一个帐户),因此不会发出POST请求。
ceejayoz '16

7

当您希望URL反映页面状态时,请使用GET。这对于查看动态生成的页面(例如此处看到的页面)很有用。POST应该以表单的形式提交数据,例如当我单击“ Post Your Answer”按钮时。由于它不会在路径后生成参数字符串,因此它还会生成一个更简洁的URL。


6

因为GET纯粹是URL,所以它们可以被Web浏览器缓存,并且可以更好地用于诸如一致生成的图像之类的事情。(设置到期时间)

引人入胜的页面上的一个示例:http : //www.gravatar.com/avatar/4c3be63a4c2f539b013787725dfce802? d=monsterid

GET可能会稍微提高性能,某些Web服务器在调用处理程序之前将POST内容写入临时文件。

要考虑的另一件事是大小限制。GET受URL大小限制,标准限制为1024字节,尽管浏览器可能支持更多。

传输更多的数据应使用POST以获得更好的浏览器兼容性。

正如另一个发布者所写,甚至还不到这个限制,这是一个问题,URL中的任何内容都可能会出现在浏览器用户界面的其他部分,例如历史记录。


4

本质上,您无能为力。关键是您不应该在HTTP GET上修改服务器状态。HTTP代理假定,因为HTTP GET不会修改状态,所以用户一次调用HTTP GET还是1000次调用HTTP GET都没有区别。他们使用这些信息假设可以安全地返回第一个HTTP GET的缓存版本。如果违反了HTTP规范,则可能会冒用破坏HTTP客户端和代理的风险。不要这样做:)


依靠GET来保证安全和幂等的不只是浏览器:搜索引擎蜘蛛和预取浏览器(如fastfox)也依赖于此。
Frank Farmer 2010年

@gili,最后有人得到正确答案。我真的很惊讶有多少人弄错了这个。竖起大拇指!
lubos hasko 2010年

4

这涉及到REST的概念以及如何使用Web。在Software Engineering广播中有一个出色的播客,深入讨论了Get和Post的用法。

Get用于从服务器中提取数据,而无需执行更新操作。想法是,您应该能够反复使用相同的GET请求,并返回相同的信息。该URL在查询字符串中具有获取信息,因为该URL可以轻松地发送给其他系统和人,例如可以在哪里找到东西的地址。

应该使用Post(至少是基于Web的REST架构)将信息推送到服务器/告诉服务器执行操作。例如:更新此数据,创建此记录。


“在软件工程电台上有一个很棒的播客,深入讨论了Get and Post的用法。” 它在哪里?
9:04

我已经添加了一个链接。
kemiller2002 '02

这就是这种联系:se-radio.net/2008/05/episode-98-stefan-tilkov-on-rest我也编辑了上面的链接,尽管我没有编辑权,必须经过同行评审,等等。
MrBoJangles 2011年

假设我有一个接受文件作为输入的端点,对该文件进行了一些处理(例如,基于正则表达式提取数据)并返回JSON数据,然后可以使用GET请求将文件上传到服务器。还是应该使用POST请求?
变量

4

1.3选择HTTP GETPOST

在以下情况下使用GET:

    The interaction is more like a question (i.e., it is a safe operation such as a query, read operation, or lookup).

在以下情况下使用POST:

    The interaction is more like an order, or
    The interaction changes the state of the resource in a way that the user would perceive (e.g., a subscription to a service), or
    The user be held accountable for the results of the interaction.

来源


3

我看不到使用get的问题,我将它用于将事情保留在查询字符串中的简单事情。

使用它来更新状态(如GET delete.php?id=5来删除页面)非常有风险。人们发现,当Google的Web加速器开始预提取页面上的URL时,它会点击所有“删除”链接并清除人们的数据。搜索引擎蜘蛛也会发生同样的事情。



3

RFC 2616

9.3 GET
GET方法意味着检索Request-URI标识的任何信息(以实体形式)。如果Request-URI指的是数据产生过程,则应将产生的数据作为响应中的实体而不是过程的源文本作为实体返回,除非该文本恰好是过程的输出。


9.5 POST
POST方法用于请求源服务器接受请求中包含的实体作为请求行中Request-URI标识的资源的新从属。POST旨在允许采用统一的方法来覆盖以下功能:

  • 注释现有资源;
  • 将消息发布到公告板,新闻组,邮件列表或类似的文章组;
  • 向数据处理过程提供数据块,例如提交表单的结果;
  • 通过附加操作扩展数据库。

POST方法执行的实际功能由服务器确定,通常取决于Request-URI。发布的实体从属于该URI,其方式与文件从属于包含该实体的目录,新闻文章从属于其发布到的新闻组或记录从属于数据库的方式相同。

POST方法执行的操作可能不会导致可以由URI标识的资源。在这种情况下,适当的响应状态是200(确定)或204(无内容),这取决于响应是否包括描述结果的实体。


2

当我不希望人们看到QueryString或QueryString变大时,我会使用POST。另外,文件上传需要POST。

我没有看到使用GET的问题,而是将它用于将事情保留在QueryString上的简单事情。

使用GET也可以链接到特定页面,而POST也不起作用。


为什么我们不能使用GET进行文件上传?
变量

1

最初的目的是使用GET来取回数据,而POST可以是任何东西。我使用的经验法则是,如果将任何内容发送回服务器,则使用POST。如果我只是调用URL来获取数据,则使用GET。


1

阅读Wikipedia中有关HTTP文章。它将解释协议是什么以及它的作用:

得到

请求表示指定资源。请注意,不应将GET用于引起副作用的操作,例如将其用于在Web应用程序中执行操作。原因之一是机械手或搜寻器可以随意使用GET,而不必考虑请求应引起的副作用。

POST 将要处理的数据(例如,从HTML表单)提交到标识的资源。数据包含在请求的正文中。这可能会导致创建新资源或现有资源的更新,或者两者都有。

W3C有一个名为URI,可寻址性以及HTTP GET和POST用法的文档该文档解释了何时使用什么。引用

1.3选择HTTP GET或POST的快速清单

  • 在以下情况下使用GET:
    • 交互更像是一个问题(即,它是一种安全的操作,例如查询,读取操作或查找)。

  • 在以下情况下使用POST:
    • 互动更像是订单,或者
    • 交互以用户将感知的方式(例如,对服务的订阅)改变资源状态,或者o使用户对交互结果负责。

但是,在最终决定使用HTTP GET或POST之前,也请考虑敏感数据的注意事项和实际注意事项。

一个实用的示例是您提交HTML表单的任何时候。您可以为表单操作指定发布获取。PHP将相应地填充$ _GET和$ _POST。


1

在PHP中,POST数据限制通常由设置php.iniGET我认为受服务器/浏览器设置的限制-通常在255字节左右。


1

w3schools.com

什么是HTTP?

超文本传输​​协议(HTTP)旨在启用客户端和服务器之间的通信。

HTTP充当客户端和服务器之间的请求-响应协议。

Web浏览器可能是客户端,托管网站的计算机上的应用程序可能是服务器。

示例:客户端(浏览器)向服务器提交HTTP请求;然后服务器将响应返回给客户端。响应包含有关请求的状态信息,也可能包含所请求的内容。

两种HTTP请求方法:GET和POST

用于客户端和服务器之间的请求响应的两种常用方法是:GET和POST。

GET –从指定资源请求数据POST –将要处理的数据提交到指定资源

在这里,我们区分主要区别:

在此处输入图片说明


1
对于搜索者和读者来说,将图像的内容输入答案中会更好。另外,答案的第一部分对回答问题并没有真正的帮助。
Dave Schweisguth '16

此处复制粘贴-您必须正确引用您的来源,并且该来源的许可证必须允许重复使用,我认为w3schools不会这样做。除此之外,您是否真的认为这增加了其他25个答案未涵盖的内容?
本杰明·W.

1

POST GET PUT DELETE的简单版本

  • 使用GET-当您想要获取基于任何ID或名称的任何资源(如数据列表)时
  • 使用POST-要将任何数据发送到服务器时。请记住,POST是一项繁重的操作,因为对于更新,我们应该在内部使用PUT而不是POST POST将创建新资源
  • 使用PUT-当您

4
“使用PUT-何时使用”句子的其余部分在哪里?

很高兴有人很喜欢这个答案的前两个项目符号,以至于他们在没有最后一个项目符号的情况下都赞成它,哈哈:'-)
pooley1994

0

一件重要的事情是,您提交的所有内容GET都将通过URL公开。其次,正如Ceejayoz所说,URL的字符数有限制。


0

另一个区别是POST通常需要两个HTTP操作,而GET仅需要一个HTTP操作。

编辑:我应该澄清-常见的编程模式。通常,出于各种原因,使用纯正的HTML网页响应POST是一个可疑的设计,其中一个烦人的原因是“您必须重新提交此表单,您希望这样做吗?” 按下返回按钮。


2
POST不需要2 http操作。
Billy ONeal

3
post-redirect-get需要2个操作:en.wikipedia.org/wiki/Post/Redirect/Get
cherouvim 2010年

1
POST可能需要2次往返服务器-常见的模式是使用expect: 100-continue标头进行POST ,然后仅在服务器响应时发送数据100 CONTINUE
Frank Farmer 2010年

不错的文章cherouvim,我从不知道该模式有一个名字。
Plynx

@cherouvim:发布重定向get可以,但是普通发布则不可以。您可能只是获得相同的结果而获得重定向。它与表单用于提交的协议无关。
Billy ONeal

0

就像其他人回答的那样,get的URL大小是有限制的,并且文件只能通过post提交。

我想补充一个CAN使用get将内容添加到数据库中,并使用post来执行操作。当脚本收到帖子或获取信息时,它可以执行作者希望执行的任何操作。我认为对本书的措辞或阅读方式缺乏理解。

脚本作者使用帖子来更改数据库,并仅使用get来获取信息。

脚本语言提供了许多访问请求的方法。例如,PHP允许使用$_REQUEST来检索帖子或获取。每个人都应该有利于更具体的避免这种情况$_GET$_POST

在Web编程中,还有更多的解释空间。有一个该做什么,一个可以做什么,但是哪个更好呢?幸运的是,在这种情况下,没有歧义。您应该使用帖子来更改数据,并且应该使用get来检索信息。


0

Gorgapor,mod_rewrite仍然经常使用GET。它仅允许将友好的URL转换为带有GET查询字符串的URL 。


-1

HTTP Post数据没有指定的数据量限制,因为不同的浏览器对GET的限制也不同。RFC 2068指出:

服务器应谨慎使用255个字节以上的URI长度,因为某些较旧的客户端或代理实现可能无法正确支持这些长度

具体来说,您应该针对它们的用途使用正确的HTTP构造。HTTP GET应该没有副作用,可以通过HTTP代理等安全地刷新和存储。

当您要针对url资源提交数据时,将使用HTTP POST。

使用HTTP GET的典型示例是在Search上,即Search?Query = my + query。使用HTTP POST的典型示例是将反馈提交到在线表单。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.