GET和POST请求区别

关于http协议GET和POST方法的区别我们可以从各处得到比较一致的答案,今天我们来填一个面试中可能碰到的一个坑。

当面试官问你“你觉得GET和POST有什么区别"时,我们可能会想到以下几点(来源于网络):

  • GET在浏览器回退时是无害的,而POST会再次提交请求。
  • GET产生的URL地址可以被Bookmark,而POST不可以。
  • GET请求会被浏览器主动cache,而POST不会,除非手动设置。
  • GET请求只能进行url编码,而POST支持多种编码方式。
  • GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
  • 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
  • GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
  • GET参数通过URL传递,POST放在Request body中。
  • GET请求在URL中传送的参数是有长度限制的,而POST么有。

以上答案除了最后2条基本没什么问题,我们现在测试一下到底什么情况。

在HTTP协议中并没有明确论述不同的请求方法使用的传送数据方式(url,body)不同,所以我们假设没有这种区别。

我们实现一个的socket server 端程序进行测试

package main

import (
	"fmt"
	"log"
	"net"
)

func main() {
	l, err := net.Listen("tcp", ":8080")
	if err != nil {
		log.Fatalln("err:", err)
	}
	defer l.Close()

	for {
		c, err := l.Accept()
		if err != nil {
			log.Fatalln("err:", err)
		}
		go process(c)

	}
}

func process(c net.Conn) {
	defer func() {
		c.Close()
		if err := recover(); err != nil {
			log.Println("process error:", err)
		}
	}()
	rH := `HTTP/1.1 200 OK
Content-Type:"application/json"`
	rSegmentation := "\r\n\r\n"
	rB := `{"data":"success"}`
	resp := rH + rSegmentation + rB

	bs := make([]byte, 1024)
	// 读请求
	n, _ := c.Read(bs)
	fmt.Println(string(bs[:n]))
	// 响应
	c.Write([]byte(resp))
}

GET方法通过url传递数据如下 

server接收到的http请求

GET方法通过body传递数据如下

server接收到的请求

 POST方法通过url传递数据

server接收到的请求

 

 POST方法通过body传递数据

 

server接收到的请求

 

上述四种测试case均成功,所以“GET参数通过URL传递,POST放在Request body中”和“GET请求在URL中传送的参数是有长度限制的,而POST么有”是错误的。具体来说:

  • 无论POST还是GET方法,传递数据(参数)既可通过URL也可以通过body
  • POST或者GET方法如果通过body传递数据(参数)是没有长度限制的
  • POST或者GET方法通过URL传递数据理论上也没有长度限制(因为url存在于http协议的header部分,而http header并没有长度限制)
  • 通常所说的参数数据限制是指浏览器或者werbserver会的一种设定,假如自己实现client和server完全能做到不限制长度

 

所以从协议角度来看GET和POST本质上并没有区别.

posted @ 2019-02-20 13:15  weelin_area  阅读(3583)  评论(0编辑  收藏  举报