不再以讹传讹,GET和POST的真正区别_有鉴于此,多数服务器出于安全啦、稳定啦方面的考虑-程序员宅基地

技术标签: php  web开发  

如果有人问你,GET和POST,有什么区别?你会如何回答?

我的经历

前几天有人问我这个问题。我说GET是用于获取数据的,POST,一般用于将数据发给服务器之用。

这个答案好像并不是他想要的。于是他继续追问有没有别的区别?我说这就是个名字而已,如果服务器支持,他完全可以把GET改个名字叫GET2。他反问道,那就是单纯的名字上的区别喽?我想了想,我觉得如果说再具体的区别,只能去看RFC文档了,还要取决于服务器(指Apache,IIS)的具体实现。但我不得不承认,我的确没有仔细看过HTTP的RFC文档。于是我说,我对HTTP协议不太熟悉。这个问题也就结束了。

最普遍的答案

回来之后寻思了很久,他到底是想问我什么?我一直就觉得GET和POST没有什么除了语义之外的区别,自打我开始学习Web编程开始就是这么理解的。

可能很多人都已经猜到了,他要的答案是:

  1. GET使用URL或Cookie传参。而POST将数据放在BODY中。
  2. GET的URL会有长度上的限制,则POST的数据则可以非常大。
  3. POST比GET安全,因为数据在地址栏上不可见。

但是很不幸,这些区别全是错误的,更不幸的是,这个答案还是Google搜索的头版头条,然而我根本没想着这些是答案,因为在我看来他们都是错的。我来一一解释一下。

1. GET和POST与数据如何传递没有关系

GET和POST是由HTTP协议定义的。在HTTP协议中,Method和Data(URL, Body, Header)是正交的两个概念,也就是说,使用哪个Method与应用层的数据如何传输是没有相互关系的。

HTTP没有要求,如果Method是POST数据就要放在BODY中。也没有要求,如果Method是GET,数据(参数)就一定要放在URL中而不能放在BODY中。

那么,网上流传甚广的这个说法是从何而来的呢?我在HTML标准中,找到了相似的描述。这和网上流传的说法一致。但是这只是HTML标准对HTTP协议的用法的约定。怎么能当成GET和POST的区别呢?

而且,现代的Web Server都是支持GET中包含BODY这样的请求。虽然这种请求不可能从浏览器发出,但是现在的Web Server又不是只给浏览器用,已经完全地超出了HTML服务器的范畴了。

知道这个有什么用?我不想解释了,有时候就得自己痛一次才记得住。

2. HTTP协议对GET和POST都没有对长度的限制

HTTP协议明确地指出了,HTTP头和Body都没有长度的要求。而对于URL长度上的限制,有两方面的原因造成:

  1. 浏览器。据说早期的浏览器会对URL长度做限制。据说IE对URL长度会限制在2048个字符内(流传很广,而且无数同事都表示认同)。但我自己试了一下,我构造了90K的URL通过IE9访问live.com,是正常的。网上的东西,哪怕是Wikipedia上的,也不能信。
  2. 服务器。URL长了,对服务器处理也是一种负担。原本一个会话就没有多少数据,现在如果有人恶意地构造几个几M大小的URL,并不停地访问你的服务器。服务器的最大并发数显然会下降。另一种攻击方式是,把告诉服务器Content-Length是一个很大的数,然后只给服务器发一点儿数据,嘿嘿,服务器你就傻等着去吧。哪怕你有超时设置,这种故意的次次访问超时也能让服务器吃不了兜着走。有鉴于此,多数服务器出于安全啦、稳定啦方面的考虑,会给URL长度加限制。但是这个限制是针对所有HTTP请求的,与GET、POST没有关系。
安全不安全和GET、POST没有关系

我觉得这真是中国特色。我讲个小段子,大家应该可以体会出这个说法多么的可笑。

觉得POST数据比GET数据安全的人会说

“防君子不防小人;中国小白多,能防小白用户就行了。”

“哼,”我不以为然,“那你怎么不说,URL参数都Encode过了,或是Base64一下,小白也看不懂啊。”

那人反驳道,“Encode太简单了,聪明点儿的小白很容易就可以Decode并修改掉。”

我笑道,“五十步笑百步耳,再聪明点儿的小白还会截包并重发呢,Opera就有这功能。”

那人阴险地祭出神器——最终解释权,说,“这个不算小白。”

我日啊。

最后一点儿感想

我之前一直做Windows桌面应用,对Web开发无甚了解,直到一年多前转做服务器端开发,才开始接触到HTTP。(注意,我说的是HTTP,不是HTML。服务器开放接口是基于REST理念设计的,使用的协议是HTTP,但是传输的内容不是HTML。这不是Web Server,而是一个Web Service)

所以我对于GET和POST的理解,是纯粹地来源于HTTP协议。他们只有一点根本区别,简单点儿说,一个用于获取数据,一个用于修改数据。具体的请参考RFC文档。

如果一个人一开始就做Web开发,很可能把HTML对HTTP协议的使用方式,当成HTTP协议的唯一的合理使用方式。从而犯了以偏概全的错误。

可能有人会觉得我钻牛角尖。我只是不喜欢模棱两可,不喜欢边界不清、概念不明,不喜欢“拿来主义”,也不喜欢被其它喜欢钻牛角尖的人奚落得无地自容。

“知之为知之,不知为不知,是知也。”

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zndy10/article/details/74942941

智能推荐

【Daily Games——工具篇】:LuaStudio的简易上手教程-程序员宅基地

文章浏览阅读2.4k次。实习第二天Lua直接上手体验,各种嵌套的内容像html实际代码体验类似c上手luastudio,增加断点调试,修改逻辑发现bug最近登录角色level显示错误创建自定义位置解决项目,导入项目文件夹。添加现有项Unity此时没有运行代码,调试窗口附加到进程,启动调试右侧会显示调用方法。 实习第三天涉及问题 :UI错位问题 其中宝箱尺..._luastudio

oracle启动/关闭/查看监听+启动/关闭/查看数据库实例命令_oracle启动监听-程序员宅基地

文章浏览阅读9.9k次,点赞5次,收藏29次。(1)以sys用户登录oracle—— sqlplus / as sysdba。(2)查看监听—— lsnrctl status。(1)启动监听—— lsnrctl start。(3)关闭监听—— lsnrctl stop。(3)关闭数据库实例—— shutdown。(2)开启数据库实例—— startup。(4)退出sql命令行界面—— quit。启动oracle第一步启动监听,第二步启动数据库实例。_oracle启动监听

JavaWeb网上书城项目_javaweb网上书店-程序员宅基地

文章浏览阅读2w次,点赞131次,收藏671次。一、需求分析用JSP/Servlet技术开发一个网上书店,主要完成以下功能:用户:注册与登录,用户信息的修改图书:图书显示,图书的购买,购物车的管理。图书的添加,删除,查询二、系统设计1)创建相关的数据库表;2)使用MVC架构或者JSP+JavaBean,至少一个功能模块使用MVC;3)在JSP中综合使用EL 表达式,JSTL标记库,JavaBean ;4)使用过滤器完成请求参数编码的设置或登录权限的控制;5)正确完成Servlet和过滤器的配置6)使用数据库连接池进_javaweb网上书店

UI——day20.lpad和watch设计规范以及适配_ipad设计ui文字行距-程序员宅基地

文章浏览阅读678次。ipad的尺寸规范现如今存在的ipad机型有哪些?那主流的设计尺寸有哪些呢?3.字体规范Apple Watch尺寸规范首屏图标80px (38mm)88px (42mm)长看图标80px (38mm)88px (42mm)短看图标172px (38mm)196px (42mm)文字规范标题36px正文标题32px正文30px备注、脚注、辅助文字24px、26pxwatch设计主题思想轻量:Apple Wa.._ipad设计ui文字行距

BellmanFord算法 讲解 AcWing 853. 有边数限制的最短路 带注释_蓬蒿人 acwing-程序员宅基地

文章浏览阅读111次。题目链接算法:BellmanFord算法 O(n∗m)O(n*m)O(n∗m)存在负权边时使用 特别适合本题这种问不超过k条边的最短路径的情景讲一下算法流程首先将图以结构体数组形式存储 BellmanFord算法特别自由 怎么存都可以struct Edge{ int a,b,c;//ab为起点 终点 c为权重}edge[10010];然后调用bellmanford函数,在函数中 先将存储最短路径的dist数组初始化为正无穷(0x3f3f3f3f)接下来开始一个二重循环 外面的大循_蓬蒿人 acwing

PMM监控MySQL-程序员宅基地

文章浏览阅读109次。一、PMM-SERVER1. 安装dockeryum install -y docker-io2. 拉取pmm-server镜像docker pull percona/pmm-server:latest3. 创建持久化容器docker create \ -v /opt/prometheus/data \ -v /opt/consul-data \ -v /var/l..._pmm 1.12 监控主备的mysql

随便推点

(1)从键盘循环录入录入一个字符串,输入“end“表示结束 (2)将字符串中大写字母变成小写字母,小写字母变成大写字母,其它字符用“*“代替,并统计字母的个数 举例: 键盘录入:Hello_换行不表示结束符,做字符统计,但用一个特殊的字符串“#end”来表示结束符,该结束-程序员宅基地

文章浏览阅读633次。(1)从键盘循环录入录入一个字符串,输入"end"表示结束(2)将字符串中大写字母变成小写字母,小写字母变成大写字母,其它字符用"*"代替,并统计字母的个数举例:键盘录入:Hello12345World输出结果:hELLO*****wORLD总共10个字母package test7_2;import java.util.Scanner;public class Demo02 { public static void main(String[] args) { while(true_换行不表示结束符,做字符统计,但用一个特殊的字符串“#end”来表示结束符,该结束

CSS中1px分割线处理_分割线1px-程序员宅基地

文章浏览阅读4.7k次。 1. 1px 边框变粗问题截图如下(iPhone 6截图):如果我们把上图与我们手机系统上的 1px 边框进行对比,如下图:我们会发现,上面两个上下线条,下线条的粗细才是正确的,上线条就显得有点粗了。但是上线条我们是用纯正的 1px border生成的,而下线条我们实际是采用transform压缩了1px高度的一半模拟实现的,也就相当于 0.5px 的高度了。为什么会这样..._分割线1px

git灰度发布版本_一键实现自动化部署(灰度发布)实践-程序员宅基地

文章浏览阅读143次。在过去几年的DevOps的浪潮中,自动化、持续集成这两个概念早已深入人心(互联网技术人)。比尔盖茨先生曾经都说过:“任何技术在一个业务中使用的第一条规则就是,将自动化应用到一个高效的操作上将会放大高效。第二条就是自动化应用到一个低效操作上,则放大了低效率。”自动化部署也逐渐成为各中小型企业追求的方向,那么,今天民工哥就自动化部署的概述、自动化部署的工具、自动化部署的流程、自动化部署实践等4个方面,..._git 自动发布工具

通用RPC方案-程序员宅基地

文章浏览阅读37次。其中ServerChannelInitializer的initChannel为触发read事件时,在SerializeAdapterDecoder的decode方法的最后一个中加入ServerChannelHandler 继承 ChannelInboundHandlerAdapter继续处理read事件时,在ServerChannelHandler 的channelRead方法中使用线程池来处理读到的数据(可能是耗时操作)从而来保证不会由于处理请求导致work线程全部耗尽,而出现等待的情况。

OpenCasCade 从零开始到生成MFC单文档测试程序_wnt_wdriver.hxx-程序员宅基地

文章浏览阅读5.9k次,点赞4次,收藏17次。1.下载1.1. 安装程序 OpenCASCADExxx.exe(xxx为最新版本号,下同): http://www.opencascade.org/getocc/download/loadocc/1.2.文档OCCTDocumentationxxx.exe(xxx为最新版本号,下同): http://www.opencascade.org/getocc/download/_wnt_wdriver.hxx

java - 设计模式学习总结_java设计模式结课报告总结-程序员宅基地

文章浏览阅读870次。熟练掌握各种设计模式,并能在实际编程开发中灵活运用它们,不仅能使代码更规范,重用性更高,同时也能保证代码的可靠性,提高开发效率。这段时间又系统看了设计模式的相关内容,整理学习总结如下,文中内容如有表达有误的地方,还请指出,共同交流学习。一、概述二、7个设计原则三、创建型模式(5种)四、结构型模式(7种)五、行为型模式(11种)六、总结一、概述面向对象编程有七大原则,即经常提到_java设计模式结课报告总结