HTTP基础
HTTP基础
定义
- HTTP,即超文本传输协议(全称HyperText Transfer Protocol),是一种应用层协议。现在我们互联网通信80%以上都是基于HTTP协议的,可以说HTTP是万维网的数据通信的基础。
- HTTP作为一个协议,其实就是一个标准,一个建立在一个客户端(用户)和服务端(网站)之间请求和应答的标准。在客户端和服务器中间可能存在多个“中间层”,比如代理服务器、网关或者隧道(tunnel)。
- 通过使用浏览器或其他工具,常见的比如我们使用的谷歌浏览器,访问www.baidu.com,就相当于我们作为客户端发起一个HTTP请求到百度的服务器上指定端口(默认80)。然后百度的服务器时刻监听指定端口,一旦监听到客户端发来了请求,那么服务器就会根据请求,返回一个应答,应答中包含状态码、响应头、响应的数据等等。
发展历程
1991年发布了HTTP 0.9版,在1996年发布1.0版
1997年是1.1版,1.1版也是到今天为止传输最广泛的版本,解决了0.9/1.1版本的TCP连接重用问题
2015年发布了2.0版,其极大的优化了HTTP/1.1的性能和安全性,改为并行连接。
2018年发布的3.0版,继续优化HTTP/2,使用UDP取代TCP协议,解决丢包问题。
目前,HTTP/3 已被 Chrome,Firefox,和Cloudflare支持。
发展历程图:
百度用的HTTP版本:
-
HTTP/1.1请求方法(8种)
GET
get=拿、获取、得到
所以GET请求只用于获取服务器的资源,比如向服务器请求,获取1班所有同学的信息(查询)。浏览器发出的GET只能由一个url触发,GET请求若需要携带参数,则是直接附带在url后面的,比如https://so.csdn.net/so/search?q=http%E5%8D%8F%E8%AE%AE (中文编码,q=http协议)
来源:https://www.cnblogs.com/heyjia/p/11193857.html
POST
post=邮寄、告知
POST请求用于更新服务器资源,包括增加、删除、修改。请求的数据被包含在请求报文中,不会再url中显示。每次提交,表单的数据被浏览器用编码到HTTP请求的body里。
浏览器发出的POST请求的body主要有两种格式:
- 一是application/x-www-form-urlencoded用来传输简单的数据,大概就是"key1=value1&key2=value2"这样的格式。
- 二是multipart/form-data格式,用于传文件,因为第一种编码方式对于文件这种二进制的数据非常低效。
来源:https://www.cnblogs.com/heyjia/p/11193857.html
HEAD
与GET方法一样,都是向服务器发出获取指定资源的请求,只不过服务器不返回消息体。主要用于测试超链接的有效性等。
PUT
向指定资源位置上传其最新内容。不同于POST接收到服务器发送的请求后,可以对请求数据作出处理后,应用到多个资源上;而PUT限定了这个请求数据只能应用到指定的位置上。
DELETE
请求服务器删除Request-URI所标识的资源。
TRACE
回显服务器收到的请求,主要用于测试或诊断。
OPTIONS
这个方法可使服务器传回该资源所支持的所有HTTP请求方法。用’*'来代替资源名称,向Web服务器发送OPTIONS请求,可以测试服务器功能是否正常运作。
CONNECT
HTTP/1.1协议中预留给能够将连接改为隧道方式的代理服务器。
状态码
分类
状态码 | 类别 | 解释 |
---|---|---|
1XX | Informational信息提示 | 请求正在处理 |
2XX | Success成功 | 请求处理成功 |
3XX | Redirection重定向 | 需要进行额外操作 |
4XX | Client Error客户端错误 | 含有词法错误或者无法被执行 |
5XX | Server Error服务器错误 | 服务器处理请求出错 |
常用状态码
- 100 Continue
用于通知客户端继续。若请求只发送了一部分,那么该部分的请求服务器已经接受后,返回100告知客户端继续发送请求剩余部分。 - 200 OK
请求响应成功,返回200 - 400 Bad Request
一般可能请求方法错误,要求的是GET,结果请求用了POST。请求存在语法错误,需要修改请求后再尝试。 - 404 Not Found
找不到请求的资源,也就是服务器没有这个资源,所以请求不到,也可以在服务器拒绝请求时使用。 - 505 Internal Server Error
服务器内部错误,就要看看代码是否出错,是不是哪里报空指针,或者数据类型不匹配之类的。(debug…) - 503 Service Unavailable
服务器不可用。服务器由于临时的服务器过载或者是维护,无法响应当前请求。
请求报文
请求头
- Host : 请求的主机名和端口号
- Referer:表示请求是从哪个URL进来的
- User-Agent : 客户端使用的操作系统、浏览器版本和名称
- Accept : 客户端希望接受的数据类型,比如 Accept:text/xml(application/json)表示希望接受到的是xml(json)类型
- Content-Type:客户端发送的实体数据的数据类型。
比如,Content-Type:text/html(application/json)表示发送的是html类型。- Accept-Encoding:客户端接收的编码方式
- Cache-Control:缓存控制
响应报文
响应头
- Cache-Control:缓存控制
- ETag:请求资源的版本,如果该资源发生变化,则此属性变化。
- Location:在重定向中或者创建新资源时使用
- Set-Cookie:服务端可以设置客户端的cookie
跨域问题
产生原因
由于浏览器的同源策略限制,浏览器会拒绝跨域请求。
- 同源
如果两个页面的协议,域名,端口
都相同,则两个页面具有相同的源。如果三者种有一个不同,则为跨域。
举例:
url1(请求页面) | url2(被请求页面) | 是否跨域 |
---|---|---|
http://www.baidu.com:8080 | http://www.baidu.com:8080?p=tom | 否,三者均相同 |
http://www.baidu.com:8080 | https://www.baidu.com:8080 | 协议不同,http、https |
http://www.baidu.com:8080 | http://www.google.com:8080 | 域名不同,baidu、google |
http://www.baidu.com:8080 | http://www.baidu.com:8082 | 端口号不同,8080、8082 |
解决办法——允许跨域资源共享(CORS)
web应用——HTTP文档:
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials
CORS(Cross-Origin Resource Sharing)
CORS使用额外的 HTTP 头部信息来告诉浏览器,让在一个origin域上的web应用被允许访问来自不同origin服务器上的指定的资源。
-
CORS 是一个 W3C标准,该标准定义了在访问跨域资源时,服务端和客户端需要如何沟通,如何授权信任。所有的浏览器都支持该标准,由浏览器自动完成
-
CORS的原理是:使用 http自定义头部 ,请求头附带客户端信息,服务端验证,并且返回响应头告诉客户端是否允许访问,只需要由服务端改动,前端不需要改动。
CORS将http请求分为简单请求和非简单请求:
简单请求
理解:不会发送CORS预检请求的请求
必须满足3个条件
- 请求方法为HEAD、GET、POST中的一种
- HTTP的请求头不超过以下4种字段
Accept、Accept-Language、Content-Language、Content-Type
- 其中Content-Type的值,只能取application/x-www-form-urlencoded、multipart/form-data、text/plain 三个中的一个
解决跨域的对策:
-
step1:
浏览器在Http头部带上 Origin(原始域),表明可以访问该资源的域名,只能是单个域名或者*
Access-Control-Allow-Origin:https://www.baidu.com
!注意:只有跨域请求,或者同域时发送post请求,才会携带origin请求头 -
step2:
如需使用cookies
前端:ajax的 withCredentials 设置为 true
服务端: 响应头增加Access-Control-Allow-Credentials: true
(可选)
代码示例:
//允许跨域的域名,*号为允许所有。解决跨域访问报错
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
//将Cookie发到服务端,需要指定Access-Control-Allow-Credentials为true;
response.setHeader("Access-Control-Allow-Credentials", "true");
非简单请求
理解:会发送CORS预检请求的请求
1. 预检请求
-
预检请求,其实在真正发送请求前,先发一个询问请求过去,用于询问服务端是否支持非简单请求。
-
预检请求的请求方式是options,其请求头必须包含origin,以及两个特殊字段Access-Control-Request-Method, Access-Control-Request-Headers
字段 | 说明 |
---|---|
Access-Control-Request-Method | 列出浏览器cors请求会用的一些http请求方法 |
Access-Control-Request-Headers | 用一个逗号, 分隔的字符串,指定浏览器cors请求会额外发送的请求头字段 |
2. 预检请求 响应
- 预检响应失败,返回正常http响应,不涉及cors的头部字段。
包含的几个重要字段:
(1)Access-Control-Allow-Methods
服务器支持的所有跨域请求的方法。
(2)Access-Control-Allow-Headers
如果浏览器请求包括Access-Control-Request-Headers字段,则Access-Control-Allow-Headers字段是必需的。它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段
(3)Access-Control-Max-Age
(可选)
响应有效时间,即响应的保存时间,过期了需要重新请求。
Access-Control-Allow-Origin 、Access-Control-Allow-Credentials(同上简单请求)
代码示例:
//允许跨域的域名,*号为允许所有。解决跨域访问报错
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
//服务器支持的所有头信息字段
response.setHeader("Access-Control-Allow-Headers",
"Origin," +
"Access-Control-Request-Headers," +
"Access-Control-Allow-Headers," +
"DNT," +
"X-Requested-With," +
"X-Mx-ReqToken," +
"Keep-Alive," +
"User-Agent," +
"X-Requested-With," +
"If-Modified-Since," +
"Cache-Control," +
"Content-Type," +
"Accept," +
"Connection," +
"Cookie," +
"X-XSRF-TOKEN," +
"X-CSRF-TOKEN," +
"Authorization");
//将Cookie发到服务端,需要指定Access-Control-Allow-Credentials为true;
response.setHeader("Access-Control-Allow-Credentials", "true");
//首部字段 Access-Control-Allow-Methods 表明服务器允许客户端使用 POST, GET 和 OPTIONS 方法发起请求
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
//设置过期时间,这里设置响应最大有效时间为 86400 秒,即24 小时
response.setHeader("Access-Control-Max-Age", "86400");
参考博客:
1.HTTP请求头和响应头详解:
https://www.jianshu.com/p/9a68281a3c84
2.Http基础知识学习(一):
https://www.cnblogs.com/heyjia/p/11193857.html
3.HTTP跨域详解和解决方式:
http://www.php20.cn/article/184
4.http跨域详解:
https://segmentfault.com/a/1190000017503765
5.HTTP访问控制(跨域问题):
https://www.pianshen.com/article/9099981253/
6.CORS 简单请求+预检请求(彻底理解跨域)
https://github.com/amandakelake/blog/issues/62