# HTTP请求
在`ng s`下启动系统,并用Firefox浏览器打开http://localhost:4200。查看控制台中的网络选项卡,然后刷新界面,点击如下记录:
![image-20210302153533938](https://img.kancloud.cn/61/27/6127b6641b5e75faba9cf754ddb1b0d0_1386x252.png)
在弹出的网络请求详情中将查看到如下数据:
![image-20210302153800262](https://img.kancloud.cn/ec/3d/ec3dc9d0122c0b66f6301f08a2a3bfb5_1710x1000.png)
上图中标明了一个http请求的4个要素:请求方法method、请求地址url、请求头header、请求主体body。在发起的get请求中,请求主体为空:
![image-20210302154139057](https://img.kancloud.cn/89/b0/89b0f93ef984d9c6e0590f37c58304df_858x174.png)
同时有请求就必然有响应,http请求对应的响应有两部分组成:响应头header以及响应主体body。
![image-20210302154324166](https://img.kancloud.cn/20/5e/205e52c850c038420bfa27ca4eca6456_1926x632.png)
在响应主体为返回了两个教师数据:
![image-20210302154403811](https://img.kancloud.cn/a5/cb/a5cb61966794f85575439c66a7cac68e_1532x786.png)
接下来,我们详细的解读一下web开发的基础 ---- http协议。
## Http
当前访问网页,大多数是以https打头的网址,比如https://www.baidu.com,https://www.jd.com,https是在http的基础上增加了安全机制,它使得http传输更加的安全。在此我们仅讨论做为https基本的http。在网络中,有很多以`P`结尾的专有名词,比如`TCP`、`DHCP`等,这里的`P`代表`protocol`,即协议。http的全称为:HyperText Transfer Protocol ,即常说的超文本传输协议。
所谓的协议其实是一种规范,比如我们可以把现实生活中的靠右行驶的交通规则称为协议,也可以将红灯停绿灯停称为一种协议。
HTTP是一种能够获取如 HTML 这样的网络资源的** [protocol](https://developer.mozilla.org/en-US/docs/Glossary/Protocol)(通讯协议)。**它是在 Web 上进行数据交换的基础,是一种 client-server 协议,也就是说,请求通常是由像浏览器这样的接受方发起的。一个完整的Web文档通常是由不同的子文档拼接而成的,像是文本、布局描述、图片、视频、脚本等等。
当客户端想要和服务端进行信息交互时,过程表现为下面几步:
1. 打开一个TCP连接:TCP连接被用来发送一条或多条请求,以及接受响应消息。客户端可能打开一条新的连接,或重用一个已经存在的连接,或者也可能开几个新的TCP连接连向服务端。
2. 发送一个HTTP**报文**:HTTP报文(在HTTP/2之前)是语义可读的。
![image-20210302160947350](https://img.kancloud.cn/a1/0e/a10e59d964c8c6de3a053b0410a575b9_1928x398.png)
3. 读取服务端返回的**报文**信息:
![image-20210302154324166](https://img.kancloud.cn/20/5e/205e52c850c038420bfa27ca4eca6456_1926x632.png)
4. 关闭连接或者为后续请求重用连接。
### Http报文
请求与响应的报文格式有所不同:
> 报文可以简单理解为数据包、或数据。
![image-20210302162359077](https://img.kancloud.cn/08/7d/087d3aeea072754a8a2234fa70b71bfe_2534x758.png)
请求由以下元素组成:
- 请求方法,比如:get、post、put等。
- 要获取的资源的路径。
- HTTP协议版本号。
- 为服务端表达其他信息的可选头部[headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers)。
- 对于一些像POST这样的方法,报文的body就包含了发送的资源,这与响应报文的body类似。
![image-20210302162833706](https://img.kancloud.cn/2a/20/2a209786cb73c457db8b76bfbf67dfe0_1584x620.png)
响应报文包含了下面的元素:
- HTTP协议版本号。
- 一个状态码([status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status)),来告知对应请求执行成功或失败,以及失败的原因。
- 一个状态信息(可选),这个信息是非权威的状态码描述信息,可以由服务端自行设定。
- HTTP [headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers),与请求头部类似。
- 可选项,比起请求报文,响应报文中更常见地包含获取的资源body(在firefox中,将响应报文以**响应**的形式查看,实际上响应的body数据紧跟header数据之后)。
综上,一个标准的http请求大概是这样的:
![image-20210302164610329](https://img.kancloud.cn/7e/85/7e85efae660b75eefeebc2de3d978e43_1438x770.png)
## Header
以请求教师列表为例,我们在仅仅使用了以下代码:
```typescript
this.httpClient.get(url)
.subscribe();
```
在此过程中并未设置haeader信息,那么浏览器中显示的header信息又具体是由谁生成的呢?具体来说,headers信息的生成是由httpClient以及浏览器组合生成的。
```
GET👈🏻 /teacher👈🏻 HTTP/1.1👌
Host: angular.api.codedemo.club:81👈🏻
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:86.0) Gecko/20100101 👌Firefox/86.0👌
Accept: application/json, text/plain, */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Origin: http://localhost:4200
Connection: keep-alive
Referer: http://localhost:4200/
Cache-Control: max-age=0
```
比如:
- 以👈🏻标注的信息是由httpClient决定的
- 以👌标注的信息则是由firefox来决定的
我们使用chrome打开同样的地址,查看相应的请求信息如下:
```
GET /teacher HTTP/1.1
Host: angular.api.codedemo.club:81
Proxy-Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Accept: application/json, text/plain, */*
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36
Origin: http://localhost:4200
Referer: http://localhost:4200/
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en;q=0.9,zh-CN;q=0.8,zh;q=0.7
```
可见,同样是向http://angular.api.codedemo.club:81/teacher发起一个http请求,firefox及chrome向后台发起的请求报文并不相同。但可以确定的是,两者均遵循了http协议,都是有效的http请求报文。
## 本节作业
1. 当发请教师新增操作时,请求的主体内容为请求的教师数据。我们来到新增教师界面,并尝试一个教师,观察会发起什么样的网络请求,观察该请求的请求方法、请求地址、请求头、请求主体、响应头以及响应主体。
2. 观察firefox以及chrome的响应报文,并对其进行比较。
3. 当我们访问某些站点时,会提醒我们浏览器或浏览器版本不兼容,你能猜到这些站点是如何获取到我们的浏览器及版本信息吗?
4. 如果你使用的是windows操作系统 ,请查看edge或ie浏览器请求http://angular.api.codedemo.club:81/teacher的请求报文。
5. 如果使用的是macos操作系统,请查看Safari浏览器的请求报文。
| 名称 | 地址 | 备注 |
| -------- | ------------------------------------------------------------ | ---- |
| HTTP概述 | [https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Overview](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Overview) | |
- 序言
- 第一章 Hello World
- 1.1 环境安装
- 1.2 Hello Angular
- 1.3 Hello World!
- 第二章 教师管理
- 2.1 教师列表
- 2.1.1 初始化原型
- 2.1.2 组件生命周期之初始化
- 2.1.3 ngFor
- 2.1.4 ngIf、ngTemplate
- 2.1.5 引用 Bootstrap
- 2.2 请求后台数据
- 2.2.1 HttpClient
- 2.2.2 请求数据
- 2.2.3 模块与依赖注入
- 2.2.4 异步与回调函数
- 2.2.5 集成测试
- 2.2.6 本章小节
- 2.3 新增教师
- 2.3.1 组件初始化
- 2.3.2 [(ngModel)]
- 2.3.3 对接后台
- 2.3.4 路由
- 2.4 编辑教师
- 2.4.1 组件初始化
- 2.4.2 获取路由参数
- 2.4.3 插值与模板表达式
- 2.4.4 初识泛型
- 2.4.5 更新教师
- 2.4.6 测试中的路由
- 2.5 删除教师
- 2.6 收尾工作
- 2.6.1 RouterLink
- 2.6.2 fontawesome图标库
- 2.6.3 firefox
- 2.7 总结
- 第三章 用户登录
- 3.1 初识单元测试
- 3.2 http概述
- 3.3 Basic access authentication
- 3.4 着陆组件
- 3.5 @Output
- 3.6 TypeScript 类
- 3.7 浏览器缓存
- 3.8 总结
- 第四章 个人中心
- 4.1 原型
- 4.2 管道
- 4.3 对接后台
- 4.4 x-auth-token认证
- 4.5 拦截器
- 4.6 小结
- 第五章 系统菜单
- 5.1 延迟及测试
- 5.2 手动创建组件
- 5.3 隐藏测试信息
- 5.4 规划路由
- 5.5 定义菜单
- 5.6 注销
- 5.7 小结
- 第六章 班级管理
- 6.1 新增班级
- 6.1.1 组件初始化
- 6.1.2 MockApi 新建班级
- 6.1.3 ApiInterceptor
- 6.1.4 数据验证
- 6.1.5 教师选择列表
- 6.1.6 MockApi 教师列表
- 6.1.7 代码重构
- 6.1.8 小结
- 6.2 教师列表组件
- 6.2.1 初始化
- 6.2.2 响应式表单
- 6.2.3 getTestScheduler()
- 6.2.4 应用组件
- 6.2.5 小结
- 6.3 班级列表
- 6.3.1 原型设计
- 6.3.2 初始化分页
- 6.3.3 MockApi
- 6.3.4 静态分页
- 6.3.5 动态分页
- 6.3.6 @Input()
- 6.4 编辑班级
- 6.4.1 测试模块
- 6.4.2 响应式表单验证
- 6.4.3 @Input()
- 6.4.4 FormGroup
- 6.4.5 自定义FormControl
- 6.4.6 代码重构
- 6.4.7 小结
- 6.5 删除班级
- 6.6 集成测试
- 6.6.1 惰性加载
- 6.6.2 API拦截器
- 6.6.3 路由与跳转
- 6.6.4 ngStyle
- 6.7 初识Service
- 6.7.1 catchError
- 6.7.2 单例服务
- 6.7.3 单元测试
- 6.8 小结
- 第七章 学生管理
- 7.1 班级列表组件
- 7.2 新增学生
- 7.2.1 exports
- 7.2.2 自定义验证器
- 7.2.3 异步验证器
- 7.2.4 再识DI
- 7.2.5 属性型指令
- 7.2.6 完成功能
- 7.2.7 小结
- 7.3 单元测试进阶
- 7.4 学生列表
- 7.4.1 JSON对象与对象
- 7.4.2 单元测试
- 7.4.3 分页模块
- 7.4.4 子组件测试
- 7.4.5 重构分页
- 7.5 删除学生
- 7.5.1 第三方dialog
- 7.5.2 批量删除
- 7.5.3 面向对象
- 7.6 集成测试
- 7.7 编辑学生
- 7.7.1 初始化
- 7.7.2 自定义provider
- 7.7.3 更新学生
- 7.7.4 集成测试
- 7.7.5 可订阅的路由参数
- 7.7.6 小结
- 7.8 总结
- 第八章 其它
- 8.1 打包构建
- 8.2 发布部署
- 第九章 总结