MVC Get Vs Post

6

在学习MVC概念时,我读到过不建议在“GET”操作中放置改变服务器对象状态(如数据库更新等)的代码,这被认为是一种不好的实践。其中一个原因是“返回数据缓存”。

请问有人可以解释一下吗?

先谢谢了!

4个回答

8

这是HTTP标准。GET动词应该是幂等和安全的。

9.1.1 安全方法

实现者应该意识到软件代表用户在互联网上的交互,并且应该小心地允许用户了解他们可能采取的任何行动,这些行动可能对他们或其他人具有意外的重要性。

特别地,已经建立了约定,即GET和HEAD方法不应具有除检索之外的其他含义。这些方法应该被认为是“安全的”。这使得用户代理可以以特殊方式表示其他方法(如POST、PUT和DELETE),以便向用户表明正在请求可能不安全的操作。

当然,无法确保服务器不会生成GET请求的副作用;事实上,一些动态资源认为这是一个功能。这里的重要区别在于用户没有请求副作用,因此不能对它们负责。

http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html


是的,在这个情境下,那是一个更好的解释。已编辑。 - Samantha Branham
啊!我希望那个人没有删除他的评论。我从中学到了一些东西。幂等并不等于安全,至少在标准中是这样的。 - Samantha Branham

6
浏览器可以缓存GET请求,通常是静态数据,如图像或脚本。但是您也可以允许浏览器缓存对控制器操作的GET请求,使用[OutputCache]或其他类似方式,因此,如果为GET控制器操作打开了缓存,则单击导向/Home/Index的链接可能实际上并不在服务器上运行Index方法,而是允许浏览器从其自己的缓存中提供页面。
按照这种思路,您可以安全地在您提供的数据不发生更改(或不经常更改)的GET操作上打开缓存,并知道您的服务器操作不会每次都触发。
POST不会被浏览器缓存,因此任何POST都保证到达服务器。

一件事:[OutputCache] 不是客户端缓存,而是服务器端缓存。其他的都很有道理。 - Samantha Branham
3
实际上,这是两者兼备的(至少默认情况下是这样)。当你开启OutputCache时,请查看cache-control和相关头文件,并观察行为的网络选项卡-在OutputCache开启时,你将得到从缓存中加载页面而无需请求的结果,或者如果刷新,则会出现304-未修改的结果。如果没有OutputCache,则每个请求都会始终命中服务器。 - Joe Enos
一个问题,可能是基础问题。MVC 如何知道缓存的数据是否过时,并且它应该从数据库中实际获取更新的数据? - Sateesh Pagolu
1
你说的是浏览器,而不是MVC。但这就是缓存控制器操作(或任何缓存)的问题所在。当服务器第一次发送页面时,它会给出一个过期日期。从浏览器的角度来看,它可以使用该缓存页面直到那时为止。除非你在浏览器上按下“F5”,或者将一个随机查询字符串值附加到URL上,否则浏览器无法知道你想要一个新的副本。我建议在你确定数据在缓存过期之前不会过时,或者除非你有一个在需要时附加随机查询字符串值的策略,否则不要打开缓存。 - Joe Enos

3
暂时忽略缓存。另一种思考方式是,在搜索引擎的索引/爬取过程中,它们将存储HTTP GET链接,因此它们会出现在搜索结果中。
假设您的/Home/IndexGET方式实施,但它会从数据库中删除一行记录,每当该链接在搜索引擎上显示并且有人点击它时,您就会删除一行记录,很快您就会有很多被删除的行。

1
HTTP规范指出,GET和HEAD应该是幂等的,即它们不应该改变服务器状态。
其中一个实际方面是,搜索机器人会针对任何已知的链接发出GET请求。如果这样的GET更改了未意图更改的用户数据,则会有问题。
幂等性还有另一个好处,客户端可以缓存GET的结果(使用HTTP头来控制)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接