HTTP 基本概念

HTTP Request Methods

GET、POST 专业名称是 HTTP Request Methods。但 HTTP Request Methods 不只是 GET 和 POST,完整列表如下:

  • GET
  • POST
  • PUT
  • DELETE
  • HEAD
  • OPTIONS
  • TRACE
  • CONNECT
  • PATCH

REST 使用前四个:GET、POST、PUT、DELETE。因些这四个也是经常被一块提及的,将这四个作为关键字进行搜索,你会得到更深入的结果。

在一般的 Web 开发中,GET 和 POST 用得最多。

Safe Methods(安全方法)

RFC 2616 中定义如下(后面有翻译):

Implementors should be aware that the software represents the user in their interactions over the Internet, and should be careful to allow the user to be aware of any actions they might take which may have an unexpected significance to themselves or others.

In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered "safe". This allows user agents to represent other methods, such as POST, PUT and DELETE, in a special way, so that the user is made aware of the fact that a possibly unsafe action is being requested.

Naturally, it is not possible to ensure that the server does not generate side-effects as a result of performing a GET request; in fact, some dynamic resources consider that a feature. The important distinction here is that the user did not request the side-effects, so therefore cannot be held accountable for them.

网址:http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.1

维基百科中的说明(对 RFC 2616翻译):

开发者应当意识到他们的软件代表了用户在因特网上进行交互,并且应当告知用户,他们正在进行的操作可能对他们自身或者其他人有未曾预料的重要影响。

特别地,对于GET和HEAD方法而言,除了进行获取资源信息外,这些请求不应当再有任何其他意义。也就是说,这些方法应当被认为是“安全的”。客户端应当使用其他“非安全”方法,例如POST,PUT及DELETE来以特殊的方式(通常是按钮而不是超链接)使得客户能够意识到可能要负的责任(例如一个按钮带来的资金交易)或者被告知正在请求的操作可能是不安全的(例如某个文件将被上传或删除)。

但是,不能想当然地认为服务器在处理某个GET请求时不会产生任何副作用。事实上,很多动态资源会把这作为其特性。这里重要的区别在于用户并没有请求这一副作用,因此不应由用户为这些副作用承担责任。

拓扑图

GET 与 POST 的区别

综上所述,可总结如下:

  • GET 仅用来获取查看信息,不能改变服务器信息。
  • POST 用来改变服务器信息。

这里说的改变,包括增加、修改和删除。

这是 HTTP 协议中的要求,众多浏览器和浏览器插件都遵守这些约定。如果你的代码不按照这约定来,可能会出现严重的后果。

使用 GET 改变服务器信息的严重后果

假定你编写的 Web 程序或网站允许 GET 提交的修改,比如允许用户通过以下 Url 直接删除编写为 1024 的订单:

~/orders/delete/1024

那么在订单的管理(或列表)页面,你可能会定义一个删除连接如下:

<a href="/orders/delete/1024">删除</a>

当然不会这么简单,一般都会在删除之前会提示用户一下,加上确认提示脚本:

<a href="/orders/delete/1024" onclick="return confirm('确实要删除吗?')">删除</a>

(说明:我在这里只是示简单例下,添加确认删除还是建议使用 Unobtrusive JavaScript 方式,可以使用 jQuery。)

很多开发人员以为这样就万事大吉了,有了确认提示,也不怕误删。但问题就恰恰出在这里,2005年时,谷歌发布了一款浏览器加速插件:Google Web Accelerator(以下简称 GWA),让这种问题严重的暴露了出来。

GWA 通过多种技术来加速,其中一种就是页面预先加载:比如你在查看我这篇文章的时候,GWA 可能把我前一篇或其它文章预先在后台下载,这样你在点击时,就节省了时间,起到了加速的效果。

GWA 的预先加载是根据当前页面中的链接来的,根据 HTTP 的协议,点击链接时使用 GET 方法获取信息,因些不会对服务器造成影响。因此 GWA 会放心的加载当前页面链接对应的网页。当然也可能会加速上面提到的订单删除链接,GWA 会无视你的确认删除脚本,直接从后台把 "/orders/delete/1024" 载入,也就意味着 1024 订单已经被删除了。

GWA 发布后,很多网站出现了很多莫名其妙的问题,数据无故丢失,商品自动加入了用户的购物车,用户无端地被扣款…

一时问题很严重,后来发现的原因的所在,就是网站开发者没有遵守 HTTP 约定,没有弄明白 GET 和 POST 的区别。

而如今,谷歌发布的 Chrome 浏览器,类似的加速功能集成了进去,你可以在 设置 - 显示高级设置 里面看得到:

所以,对服务器有改变的一定要用 POST,GWA 和类似的插件不会提交 POST 表单加速的。

删除、查看用户信息收费(比如人才网、婚恋网)、加入购物车等操作还是放在 POST 表单中用 Button 来吧。

再回头读维基百科中对 Safe Methods 的说明,相信你会明白很多。

注意:但也不是所有对服务器有改变的都要用 POST,比如你点击本文下面的 前一篇博文链接 ,我的文章访问量可能+1,对服务器有所改变,但这种改变是轻微的,影响不大(相对删除、扣款来说),可以放心的使用链接(GET 方式)。

基它一些区别:

  • 使用 GET 表单查询,查询结果页面可以收藏;POST 表单不行。
  • 向服务器发送文件只能使用 POST 表单。

能想到的大致这些吧。

感言

之前,我曾学习 ASP.NET 多年,但对 HTTP 几乎一无所知,WebForm 封装了一切:

  • 不用去考虑 POST、GET,只需知道 Postback;
  • 不用多考虑值来回传递,因为有 ViewState;
  • 不用关心 Html,因为有服务端控件。

更悲哀的是,我有很长一段时间都认为一个页面上只能有一个 Form。

后来做了一段时间 WinForm 后,开始学习 ASP.NET MVC,开始逐步了解 Html、Http 等等,也开始知道了 Post-Redirect-Get 模式等等。

看到很多人浅浅讨论 GET 和 POST,感到很无奈,WebForm 误人啊。要想进步,还是学学 ASP.NET MVC 吧!

 

玩转GET 和 POST的更多相关文章

  1. 玩转spring boot——快速开始

    开发环境: IED环境:Eclipse JDK版本:1.8 maven版本:3.3.9 一.创建一个spring boot的mcv web应用程序 打开Eclipse,新建Maven项目 选择quic ...

  2. [C#] 软硬结合第二篇——酷我音乐盒的逆天玩法

    1.灵感来源: LZ是纯宅男,一天从早上8:00起一直要呆在电脑旁到晚上12:00左右吧~平时也没人来闲聊几句,刷空间暑假也没啥动态,听音乐吧...~有些确实不好听,于是就不得不打断手头的工作去点击下 ...

  3. [C#] 了解过入口函数 Main() 吗?带你用批处理玩转 Main 函数

    了解过入口函数 Main() 吗?带你用批处理玩转 Main 函数 目录 简介 特点 方法的参数 方法的返回值 与批处理交互的一个示例 简介 我们知道,新建一个控制台应用程序的时候,IDE 会同时创建 ...

  4. 玩转spring boot——开篇

    很久没写博客了,而这一转眼就是7年.这段时间并不是我没学习东西,而是园友们的技术提高的非常快,这反而让我不知道该写些什么.我做程序已经有十几年之久了,可以说是彻彻底底的“程序老炮”,至于技术怎么样?我 ...

  5. 玩转spring boot——结合redis

    一.准备工作 下载redis的windows版zip包:https://github.com/MSOpenTech/redis/releases 运行redis-server.exe程序 出现黑色窗口 ...

  6. 玩转spring boot——AOP与表单验证

    AOP在大多数的情况下的应用场景是:日志和验证.至于AOP的理论知识我就不做赘述.而AOP的通知类型有好几种,今天的例子我只选一个有代表意义的“环绕通知”来演示. 一.AOP入门 修改“pom.xml ...

  7. 玩转spring boot——结合JPA入门

    参考官方例子:https://spring.io/guides/gs/accessing-data-jpa/ 接着上篇内容 一.小试牛刀 创建maven项目后,修改pom.xml文件 <proj ...

  8. 玩转spring boot——结合JPA事务

    接着上篇 一.准备工作 修改pom.xml文件 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=&q ...

  9. 玩转spring boot——结合AngularJs和JDBC

    参考官方例子:http://spring.io/guides/gs/relational-data-access/ 一.项目准备 在建立mysql数据库后新建表“t_order” ; -- ----- ...

  10. 玩转spring boot——结合jQuery和AngularJs

    在上篇的基础上 准备工作: 修改pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=&q ...

随机推荐

  1. 配置GitHub Push自动触发Jenkins的构建

    这里以gitbook的项目为例,GitHub中的gitbook项目部署在Jenkins中,执行git push命令时自动执行Jenkins构建,其他项目只是最后的执行脚本不同 环境准备 安装Jenki ...

  2. leveldb实现原理

    LevelDb日知录之一:LevelDb 101 说起LevelDb也许您不清楚,但是如果作为IT工程师,不知道下面两位大神级别的工程师,那您的领导估计会Hold不住了:Jeff Dean和Sanja ...

  3. Harbor删除镜像后且GC清理后,磁盘空间没有释放的问题

    1.原因 Harbor删除镜像后且GC清理后,磁盘空间没有释放.因为我们push大量相同标签的镜像,Docker 镜像由标签引用,并由唯一的摘要标识.这意味着如果myImage使用标记推送两个图像,在 ...

  4. I/O模型系列之五:IO多路复用 select、poll、epoll

    IO多路复用之select.poll.epoll IO多路复用:通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作. 应用:适用于针 ...

  5. 077、跨主机使用Rex-Ray volume (2019-04-24 周三)

    参考https://www.cnblogs.com/CloudMan6/p/7630205.html   上一节我们在docker1上创建mysql容器,并使用了 Rex-Ray volume mys ...

  6. Mac平台Clion配置GLFW+GLAD的项目

    前期的准备工作详见LearnOpenGL CN 看这篇教程的前提是假设你已经编译好了GLFW文件夹以及下载好了GLAD,不会的话可以看我的另一篇 文章的前部分: 配置 Clion新建一个项目,CMak ...

  7. 转载-IDEA项目左边栏只能看到文件看不到项目结构

    原文-https://blog.csdn.net/weixin_42362985/article/details/80538064 有时IDEA Maven项目打开左侧Project窗口本应该显示项目 ...

  8. 搭建微信小程序的本地测试服务器 json-server

    1.首先需要在windows环境下安装node.js 选择 Windows Installer 下载对应的系统版本就行,然后一路next,这种方式安装好以后会把环境变量也配置好了,直接在命令行下输入 ...

  9. SpringMVC+Apache Shiro+JPA(hibernate)整合配置

    序: 关于标题: 说是教学,实在愧不敢当,但苦与本人文笔有限,实在找不到更合理,谦逊的词语表达,只能先这样定义了. 其实最真实的想法,只是希望这个关键词能让更多的人浏览到这篇文章,也算是对于自己写文章 ...

  10. IDEA中 GIT与SVN版本控制插件的切换

    https://www.cnblogs.com/yccmelody/p/7794220.html