这是我参与「第四届青训营 」笔记创作活动的第5天
HTTP是前端开发中非常基础也是非常重要的内容。前端开发中经常遇到的跨域问题就和HTTP有关。本文将主要介绍HTTP的基础知识以及HTTP在前端开发中的应用。
初始HTTP
HTTP是一种能够获取如HTML这样的网络资源的通讯协议(protocol)。它是在Web上进行数据交换的基础,是一种client-server协议,HTTP客户程序通常是浏览器,HTTP服务器程序通常是万维网服务器。HTTP定义了这些报文的结构以及客户和服务器进行报文交换的方式。HTTP协议的目的是实现浏览器从万维网服务器获取资源。资源包括文本、声音、图像等各种多媒体文件。
协议分析
HTTP协议的工作过程如下:
- 客户浏览器进程分析URL
- 浏览器向DNS服务器请求将URL中的主机域名解析为IP地址
- DNS服务器解析出IP地址
- 浏览器用IP地址和端口与万维网服务器建立TCP连接
- 浏览器发出HTTP请求报文
- 服务器进程返回HTTP响应报文,由浏览器进行解释显示
- 释放TCP连接
HTTP协议在不断更新和完善,主要有以下5个版本。
HTTP有两类报文:请求报文和响应报文。HTTP是面向文本的,在报文中的每一个字段都是一些ASCII码串。HTTP请求报文和响应报文都是由三个部分组成的。
- 开始行:在请求报文中的开始行叫做请求行,而在响应报文中的开始行叫做状态行。
- 首部行:用来说明浏览器、服务器或报文主体的一些信息。首部可以包含多行,也可以不使用。每一个首部行中都包含首部字段名和它的值。
- 实体主体:在请求报文中称为请求主体,HTTP请求中一般不使用这个字段。在响应报文中称为响应主体。
HTTP请求报文中的方法
| 方法 | 意义 |
|---|---|
| GET | 请求一个指定资源的表示形式,使用GET的请求应该只被用于获取数据 |
| POST | 用于将实体提交到指定的资源,通常导致在服务器上的状态变化或副作用 |
| PUT | 用请求有效载荷替换目标资源的所有当前表示 |
| DELETE | 删除指定的资源 |
| HEAD | 请求一个与GET请求的响应相同的响应,但没有响应体 |
| CONNECT | 建立一个到由目标资源标识的服务器的隧道 |
| OPTIONS | 用于描述目标资源的通信选项 |
| TRACE | 沿着到目标资源的路径执行一个消息环回测试 |
| PATCH | 用于对资源应用部分修改 |
Safe (安全的)︰不会修改服务器的数据的方法(GET HEAD OPTIONS)
Idempotent(幂等)︰同样的请求被执行一次与连续执行多次的效果是一样的,服务器的状态也是一样的,所有safe的方法都是Idempotent的(GET HEAD OPTIONS PUT DELETE)
HTTP响应报文中的状态码
| 状态码 | 含义 |
|---|---|
| 200 | 客户端请求成功 |
| 301 | 资源(网页等)被永久转移到其它URL |
| 302 | 临时跳转 |
| 401 | 请求未经授权 |
| 404 | 请求资源不存在,可能是输入了错误的URL |
| 500 | 服务器内部发生了不可预期的错误 |
| 504 | 网关或者代理的服务器无法在规定的时间内获得想要的响应 |
HTTP协议是无状态协议,每次请求之间是相互独立的。当业务逻辑需要了解多次请求之间的关联时,可以使用Cookie,用来弥补HTTP协议无状态的不足。
常见场景
跨源资源共享(CORS)
前端调用的后端接口不属于同一个域(域名或端口不同),就会产生跨域问题。出于安全性,浏览器限制脚本内发起的跨源 HTTP 请求。
跨域解决方案
- CORS
- 代理服务器
- Iframe
实际应用
Axios
Axios是一个基于promise的网络请求库,可以用于node.js和浏览器。
安装
1.使用npm
npm install axios
2.使用bower
bower install axios
3.使用yarn
yarn add axios
使用
//全局配置
axios.defaults.baseURL="https://api.example.com";
//添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function(error) {
//对请求错误做些什么
return Promise.reject(error);
});
//发送请求
axios({
method: 'get',
url: 'http://test.com',
responseType: 'stream'
}).then(function (response) {
response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))
});