【计算机网络】深入解析 HTTP 中的 Restful API : GET 方法、POST 方法和 GET 和 POST 的区别_restful api post
网络原理— HTTP “方法” (method)
Restful API
1. RESTful API 是什么?
RESTful API 是一种基于 REST(Representational State Transfer)架构风格 设计的 Web API,它使用标准的 HTTP 方法(GET、POST、PUT、DELETE 等)来操作资源,并遵循以下核心原则:
- 资源(Resource):每个 URL 代表一个资源(如
/users
、/products
)。 - HTTP 方法(GET/POST/PUT/DELETE):定义对资源的操作方式。
GET
:获取资源POST
:创建资源PUT
:更新资源DELETE
:删除资源
- 无状态(Stateless):服务器不存储客户端状态,每次请求必须包含所有必要信息(如 Token)。
- 统一接口(Uniform Interface):API 设计风格一致,易于理解和使用。
- 返回 JSON/XML:通常使用 JSON 格式传输数据。
示例:
GET /api/users → 获取所有用户 POST /api/users → 创建新用户 GET /api/users/1 → 获取 ID=1 的用户 PUT /api/users/1 → 更新 ID=1 的用户 DELETE /api/users/1 → 删除 ID=1 的用户
2. 拦截器(Interceptor)属于 Spring MVC 还是 Spring Boot?
拦截器(Interceptor)本质上是 Spring MVC 的概念,但 Spring Boot 自动集成了 Spring MVC,因此可以在 Spring Boot 中使用。
拦截器(Interceptor) vs 过滤器(Filter)
拦截器的实现(Spring MVC / Spring Boot 均可)
@Componentpublic class AuthInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 在 Controller 执行前拦截(如 Token 校验) String token = request.getHeader(\"Authorization\"); if (!isValidToken(token)) { response.sendError(401, \"Unauthorized\"); return false; // 拦截请求 } return true; // 放行 } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // Controller 执行后,视图渲染前 } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 请求完成后(可用于资源清理) }}
注册拦截器(Spring Boot 配置)
@Configurationpublic class WebConfig implements WebMvcConfigurer { @Autowired private AuthInterceptor authInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(authInterceptor) .addPathPatterns(\"/api/**\") // 拦截 /api 开头的请求 .excludePathPatterns(\"/api/login\"); // 排除登录接口 }}
总结
- RESTful API 是基于 HTTP 的资源操作风格,强调无状态、统一接口。
- 拦截器(Interceptor)是 Spring MVC 的功能,但 Spring Boot 自动整合了它,因此两者都能用。
- 过滤器(Filter)属于 Servlet 规范,不依赖 Spring,适用于更底层的请求处理(如编码、安全过滤)。
如果是 Spring Boot 项目,通常直接用 Interceptor
结合 WebMvcConfigurer
进行请求拦截即可。
程序猿大佬有言:”天下方法共十斗,GET 独占八斗,POST 占一斗,剩下的方法占一斗。
“
因此,我们只要掌握了GET
和POST
,足以应付绝大多数工作情景。
1. GET方法
GET
是最常用的 HTTP 方法,常用于获取服务器上的某个资源
;
在浏览器中直接输入URL
,此时浏览器
就会发送出一个GET请求
;
另外,HTML中的link
img
script
等标签,也会触发GET请求
;
后面我们还会学习,使用 JavaScript 中的
ajax
也能构造 GET请求
在平时的 fiddler 中,抓包的数据中基本都是
HTML
,基本没有CSS
或者JS
这时候就有一个小技巧,可以回到浏览器中,按住
ctrl后再刷新页面
,重新打开 fiddler:
此时就会发现,fiddler 抓包明显抓到了更多的 css 和 js
原理:
F5 表示
刷新
,而 ctrl+F5 表示的是强制刷新
;
引入浏览器的缓存机制:
- 浏览器是从
服务器
,也就是通过网络
加载页面的;- 我们知道,缓存数据的速度为
CPU>内存>硬盘>网络带宽
,所以通常来说,从网络带宽中加载数据的速度是慢于硬盘的
;- 浏览器为了加快访问网页的速度,就会把页面依赖的一些
静态资源
(css,js,图片,字体,mp3…)缓存到硬盘
上;- 因此在我们第一次访问服务器时,需要加载包含静态资源的数据;
- 这些静态资源会在第一次访问服务器时,加载到硬盘上;后续再次访问,就不会再重新加载静态资源的数据了;
如果要在后续的访问中,
重新加载静态资源
,就需要使用强制刷新操作;强制刷新会忽略本地缓存,所有资源都从服务器中重新获取一遍;
因此使用强制刷新操作,我们就可以使用 fiddler 抓取到
更丰富的请求结果
;
打开Fiddler,访问搜狗主页,观察抓包结果:
在上面的结果中可以看到:
最上面的
是通过浏览器地址栏发送的GET请求;
下面的和 sogou 域名相关的请求,有些是通过 html 中的 link/script/img 标签产生的,例如
有些是通过 ajax 的方式产生的,例如
选中第一条:
观察请求的详细结果:
GET :
首行的第一部分
为 GET
header :
header 部分有若干个
键值对
结构;
body :
body 部分为空
:
URL query string :
因为 body 部分为空,如果需要通过 GET
给服务器发送数据
,可以通过 query string 传递
关于 GET 请求的 URL 长度问题:
网上有些资料上描述:get请求长度最多 1024kb 这样的说法是错误的.
HTTP协议由
RFC2616
标准定义:\"Hypertext Transfer Protocol–HTTP/1.1,“does not specify any requirement for URL length.”
标准原文中明确说明,没有对 URL 的长度有任何的限制
;
实际 URL 的长度,取决于
浏览器的实现
和HTTP服务器端的实现
;在浏览器端,
不同的浏览器最大长度是不同的
,但是现代浏览器支持的长度一般都很长;在
服务器端
,一般这个长度是可以配置的
.
2. POST方法
POST 方法也是一种常见的方法,多用于提交用户输入的数据给服务器
(例如登陆页面
或者上传数据
).
通过HTML中的form标签
可以构造POST请求,或者使用JavaScript的ajax
也可以构造POST请求;
在比特教务系统的登陆页面,输入用户名,密码,验证码之后,点击登陆
,就可以看到POST请求:
点击这个请求,查看请求详情:
上述是登录操作
,对于上传数据操作
,请求也会带有 body,body 保存了当前上传数据的内容;
如修改头像等操作, 图片本身是二进制的,通过特殊方式解析转码(base64 编码
,把二进制转为文本),在POST请求中,body 部分填入的就是文本数据;
另外, body 既可以填文本数据
,也可以直接填二进制数据
;
POST
首行的第一部分
为 POST
URL query string
URL 的 query string
一般为空
(也可以不为空)
header :
header 部分有若干个
键值对
结构;
body :
- body 部分
一般不为空
:- body 内的
数据格式
通过 header 中的Content-Type
指定;- body的
长度
由header中的Content-Length
指定;
3. 经典面试题:谈谈GET和POST的区别
从HTTP的定义来看:
- GET:
- GET 用于
获取资源
; - 通常情况下,GET
用于请求数据
而不改变服务器状态
。
- GET 用于
- POST:
- POST 用于
提交数据到服务器
; - 通常情况下,
会改变服务器的状态
或产生副作用
(如创建或更新资源)。
- POST 用于
由于HTTP
和浏览器
等规定,它们在应用过程中会出现一些区别:
参数传递方式:
-
GET:
- 参数放在 query String 中,
通过 URL 拼接传递
- 暴露在请求 URL中,具有
可见性
,长度有限
(取决于浏览器和服务器)。 - body 一般为空,需要传递的数据通过query string传递
- 参数放在 query String 中,
-
POST:
- 参数
放在请求体 body 中
- 通常
不可见
,长度理论上没有限制
; - query string 一般为空,需要传递的数据通过 body 传递
- 更适合传递大量数据(但是注意,POST也可以在URL上放参数!)。
- 参数
安全性(对于登录场景):
-
GET:
- 参数可见,数据
容易暴露在浏览器历史记录、日志和缓存中
- 不适合传递敏感信息。
- 参数可见,数据
-
POST:
- 数据放在请求体中,相对安全,但
需要 HTTPS 才能保证数据加密传输
。
- 数据放在请求体中,相对安全,但
幂等性(如果多次请求得到的结果一样,就视为请求是幂等的):
-
GET:
幂等
(重复请求不会改变服务器状态);- GET 设计成幂等,就可以
允许 GET 请求被缓存
;
-
POST:
非幂等
(多次请求可能导致重复创建资源或执行多次相同操作);- POST 由于不要求幂等,所以 POST 经常是不幂等的,因此
POST 请求不能被缓存
;
关于语义:
- GET完全可以用于
提交数据
,POST也完全可以用于获取数据
关于幂等性:
- 标准建议 GET 实现为幂等的;
- 实际开发中 GET 也不必完全遵守这个规则
- 主流网站都有
\"猜你喜欢\"
功能,会根据用户的历史行为,实时更新现有的结果;
关于安全性:
- 有些资料上说\"POST比GET请安全\",这样的说法是不科学的;
- 是否安全取决于
前端在传输密码等敏感信息时,是否进行加密
,和GET/ POST无关;
关于传输数据量:
- 有的资料上说\" GET传输的数据量小,POST传输数据量大 \",这个也是不科学的;
- 标准没有规定 GET 的 URL 的长度,也没有规定 POST 的 body 的长度;
- 传输数据量多少,完全取决于
不同浏览器和不同服务器之间的实现区别
;
关于传输数据类型:
有的资料上说\"GET 只能传输文本数据,POST 可以传输二进制数据\",这个也是不科学的;
GET 的 URL 确实只能放文本(
query string
无法直接传输二进制数据),但是可以针对二进制数据进行urlencode(通过base64
把二进制转码成文本);
4. 其他方法
PUT
- 与POST相似,只是具有幂等特性,一般用于更新
DELETE
- 删除服务器指定资源
OPTIONS
- 返回服务器所支持的请求方法
HEAD
- 类似于GET,只不过响应体不返回,只返回响应头
TRACE
- 回显服务器端收到的请求,测试的时候会用到这个
CONNECT
- 预留,暂无使用
这些方法的 HTTP请求
可以使用 ajax
来构造 (也可以通过一些第三方工具)
任何一个能进行网络编程的语言,都可以构造HTTP请求;
本质上就是通过
TCP socket
写入一个符合HTTP 协议
规则的字符串
.