5. 怎么理解get/post
Last updated
Was this helpful?
Last updated
Was this helpful?
这种问题, 其实如果你站在 tcp 的层面上看, 压根就没有任何区别, 无非就是http协议中的一个字段不同而已. 产生区别的只是我们人为约定的一些习惯, 比如你认定get就是从服务器拿点东西回来, 而post就是向服务器提交点数据上去, 由此衍生我们就产生了如下的习惯:
因为get取东西因此是幂等的, 而post常常用于提交某个事件(表格), 因此不幂等, 我们也用有没有副作用, 会不会产生服务器数据变动, 来描述这个结果
因为取东西无所谓因此浏览器会缓存一些get出来的东西. 而post不会做缓存
因为是取东西因此不用带body, 所有参数都拼在url里的, 让人产生了get就没有body的假象, 有人说http消息长度有限制, 其实协议本身没有讲过, 都是浏览器规定的, IE8规定2000字节, chrome能让你发更长的. 不过不建议这么干, 长的就要用post带body做了, 据我所知ES的search接口就是get带body, 因为查询参数多又长, 全写url上很难看, 不如作为json放在body里清爽
有人说安全性上有区别, 其实他这里想说的是网关, 或者nginx会做日志, 把url记录下来但是body不记, 这就造成了如果你在url里拼密码, 那你的密码会明晃晃的出现在别人的日志里, 非常舒服
一个比较有意思的问题是, 如果我们今天令所有请求都变 post 会怎样? 如果有个人就坚持这样写呢? 你准备怎么说服他? 回答是这样的:
一天之内会有几亿人访问 baidu.com
. 那么你认为这个请求是不是被服务器处理了? 答案是很多都没有, 因为大部分请求都是 get 的读请求. 除了你的浏览器会缓存一部分以外, 一些静态文件同样会被CDN缓存下来. 他们自己就能搞定一大部分的请求, 大可不必跑去给后端增加压力.
好, 现在你准备用post替代所有get, post不走缓存, 因此所有请求全都直接到访服务器, cdn直接被忽略, 这是你想看到的吗? REST的诞生不是坐家里空想出来的, 它赋予我们一部分能力, 能在只看到头的情况下, 初步判断出这个请求的意图, 比如nginx就能做到这样的事, 如果看到你是get了, 我们就会找一些缓存来解决你的问题, 在实际生产中能发挥出相当的威力
有一个比较有意思的问题是, 参数可以放在 path, query, body 里, 那放在哪儿有什么区别呢?
path/query (url) vs body :
这个很清晰了, url里的会被网关nginx记录在日志里
非ASCII字符(比如汉字) 的编码方式:
常规来说如果你放在 url 里的, 实际发出去的会被编码成一串 %2F%3D
的东西, 这种一大堆百分号东西叫 percent encoding, 就算你输入的是汉字, 浏览器会帮你编码成百分号再发出去, 看上图, 地址栏上写的是汉字, 你复制出去就变成乱码, 都浏览器干的.
如果是body里的, 虽然也会经过utf8编码, 但是不会被percent encoding
path vs query
这种比较有意思, 比如 /cars/:id
与/cars?color=blue
区别在于如果放path里用于指明一种资源, 而放query里则是一种筛选的味道