第174题 HTTP面试题总结
HTTP状态码
1XX:信息状态码100 Continue继续,一般在发送post请求时,已发送了http header之后服务端将返回此信息,表示确认,之后发送具体参数信息
2XX:成功状态码200 OK正常返回信息201 Created请求成功并且服务器创建了新的资源202 Accepted服务器已接受请求,但尚未处理
3XX:重定向301 Moved Permanently请求的网页已永久移动到新位置。302 Found临时性重定向。303 See Other临时性重定向,且总是使用GET请求新的URI。304 Not Modified自从上次请求后,请求的网页未修改过。
4XX:客户端错误400 Bad Request服务器无法理解请求的格式,客户端不应当尝试再次使用相同的内容发起请求。401 Unauthorized请求未授权。403 Forbidden禁止访问。404 Not Found找不到如何与URI相匹配的资源。
5XX:服务器错误500 Internal Server Error最常见的服务器端错误。503 Service Unavailable服务器端暂时无法处理请求(可能是过载或维护)。
常见状态码
200成功301永久重定向(配合location,浏览器自动处理)302临时重定向(配合location,浏览器自动处理)304资源未被修改403没有权限访问,一般做权限角色404资源未找到500Internal Server Error服务器内部错误502Bad Gateway503Service Unavailable504Gateway Timeout网关超时
502 与 504 的区别
这两种异常状态码都与网关 Gateway 有关,首先明确两个概念
Proxy (Gateway),反向代理层或者网关层。在公司级应用中一般使用Nginx扮演这个角色Application (Upstream server),应用层服务,作为Proxy层的上游服务。在公司中一般为各种语言编写的服务器应用,如Go/Java/Python/PHP/Node等- 此时关于 502 与 504 的区别就很显而易见
502 Bad Gateway:一般表现为你自己写的「应用层服务(Java/Go/PHP)挂了」,或者网关指定的上游服务直接指错了地址,网关层无法接收到响应504 Gateway Timeout:一般表现为「应用层服务 (Upstream) 超时,超过了Gatway配置的Timeout」,如查库操作耗时三分钟,超过了Nginx配置的超时时间
http headers
- 常见的Request Headers
Accept浏览器可接收的数据格式Accept-Enconding浏览器可接收的压缩算法,如gzipAccept-Language浏览器可接收的语言,如zh-CNConnection:keep-alive一次TCP连接重复复用CookieHost请求的域名是什么User-Agent(简称UA) 浏览器信息Content-type发送数据的格式,如application/json
- 常见的Response Headers
Content-type返回数据的格式,如application/jsonContent-length返回数据的大小,多少字节Content-Encoding返回数据的压缩算法,如gzipset-cookie
- 缓存相关的Headers
Cache Control、ExpiredLast-Modified、If-Modified-SinceEtag、If-None-Match
HTTP缓存
- 关于缓存介绍
- 为什么需要缓存?减少网络请求(网络请求不稳定性),让页面渲染更快
- 哪些资源可以被缓存?静态资源(
jscssimg)webpack打包加contenthash根据内容生成hash
- http缓存策略 (强制缓存 + 协商缓存)
- 强制缓存
- 服务端在
Response Headers中返回给客户端 Cache-Control:max-age=31536000(单位:秒)一年- Cache-Control的值
max-age(常用)缓存的内容将在max-age秒后失效no-cache(常用)不要本地强制缓存,正常向服务端请求(只要服务端最新的内容)。需要使用协商缓存来验证缓存数据(EtagLast-Modified)no-store不要本地强制缓存,也不要服务端做缓存,所有内容都不会缓存,强制缓存和协商缓存都不会触发public所有内容都将被缓存(客户端和代理服务器都可缓存)private所有内容只有客户端可以缓存
- Expires
Expires:Thu, 31 Dec 2037 23:55:55 GMT(过期时间)- 已被
Cache-Control代替
- Expires和Cache-Control的区别
Expires是HTTP1.0的产物,Cache-Control是HTTP1.1的产物Expires是服务器返回的具体过期时间,Cache-Control是相对时间Expires存在兼容性问题,Cache-Control优先级更高
- 强制缓存的优先级高于协商缓存
- 强制缓存的流程
- 浏览器第一次请求资源,服务器返回资源和
Cache-ControlExpires - 浏览器第二次请求资源,会带上
Cache-ControlExpires,服务器根据这两个值判断是否命中强制缓存 - 命中强制缓存,直接从缓存中读取资源,返回给浏览器
- 未命中强制缓存,会带上
If-Modified-SinceIf-None-Match,服务器根据这两个值判断是否命中协商缓存 - 命中协商缓存,返回
304,浏览器直接从缓存中读取资源 - 未命中协商缓存,返回
200,浏览器重新请求资源
- 浏览器第一次请求资源,服务器返回资源和
- 强制缓存的流程图

- 服务端在
- 协商缓存
- 服务端缓存策略
- 服务端判断客户端资源,是否和服务端资源一样
- 如果判断一致则返回
304(不在返回js、图片内容等资源),否则返回200和最新资源 - 服务端怎么判断客户端资源一样? 根据资源标识
- 在
Response Headers中,有两种 Last-Modified和Etag会优先使用Etag,Last-Modified只能精确到秒级,如果资源被重复生成而内容不变,则Etag更准确Last-Modified服务端返回的资源的最后修改时间If-Modified-Since客户端请求时,携带的资源的最后修改时间(即Last-Modified的值)
Etag服务端返回的资源的唯一标识(一个字符串,类似指纹)If-None-Matche客户端请求时,携带的资源的唯一标识(即Etag的值)
- Headers示例

- 请求示例 通过
Etag或Last-Modified命中缓存,没有返回资源,返回304,体积非常小
- 在
- HTTP缓存总结

- 强制缓存
- 刷新操作方式,对缓存的影响
- 正常操作:地址栏输入
url,跳转链接,前进后退 - 手动操作:
F5,点击刷新,右键菜单刷新 - 强制刷新:
ctrl + F5或command + r
- 正常操作:地址栏输入
- 不同刷新操作,不同缓存策略
- 正常操作:强缓存有效,协商缓存有效
- 手动操作:强缓存失效,协商缓存有效
- 强制刷新:强缓存失效,协商缓存失效
- 小结
- 强缓存
Cache-Contorl、Expired(弃用) - 协商缓存
Last-Modified/If-Modified-Since和Etag/If-None-Matche,304状态码 - 完整流程图
- 强缓存
从输入URL到显示出页面的整个过程
- 下载资源 :各个资源类型,下载过程
- 加载过程
DNS解析:域名 =>IP地址- 浏览器根据
IP地址向服务器发起HTTP请求 - 服务器处理
HTTP请求,并返回浏览器
- 渲染过程
- 根据
HTML生成DOM Tree - 根据
CSS生成CSSOM DOM Tree和CSSOM整合形成Render Tree,根据Render Tree渲染页面- 遇到
<script>暂停渲染,优先加载并执行JS代码,执行完在解析渲染(JS线程和渲染线程共用一个线程,JS执行要暂停DOM渲染) - 直至把
Render Tree渲染完成
- 根据
window.onload和DOMContentLoaded
window.onload页面的全部资源加载完才会执行,包括图片、视频等DOMContentLoaded渲染完即可,图片可能尚未下载
window.addEventListener('load',function() {
// 页面的全部资源加载完才会执行,包括图片、视频等
})
window.addEventListener('DOMContentLoaded',function() {
// DOM渲染完才执行,此时图片、视频等可能还没有加载完
})
演示
<p>一段文字 1</p>
<p>一段文字 2</p>
<p>一段文字 3</p>
<img
id="img1"
src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1570191150419&di=37b1892665fc74806306ce7f9c3f1971&imgtype=0&src=http%3A%2F%2Fimg.pconline.com.cn%2Fimages%2Fupload%2Fupc%2Ftx%2Fitbbs%2F1411%2F13%2Fc14%2F26229_1415883419758.jpg"
/>
<script>
const img1 = document.getElementById('img1')
img1.onload = function () {
console.log('img loaded')
}
window.addEventListener('load', function () {
console.log('window loaded')
})
document.addEventListener('DOMContentLoaded', function () {
console.log('dom content loaded')
})
// 结果
// dom content loaded
// img loaded
// window loaded
</script>
拓展:关于Restful API
- 一种新的
API设计方法 - 传统
API设计:把每个url当做一个功能 Restful API设计:把每个url当前一个唯一的资源- 如何设计成一个资源
- 尽量不用
url参数- 传统
API设计:/api/list?pageIndex=2 Restful API设计:/api/list/2
- 传统
- 用
method表示操作类型- 传统
API设计:post新增请求:/api/create-blogpost更新请求:/api/update-blog?id=100post删除请求:/api/delete-blog?id=100get请求:/api/get-blog?id=100
Restful API设计:post新增请求:/api/blogpatch更新请求:/api/blog/100delete删除请求:/api/blog/100get请求:/api/blog/100
- 传统
- 尽量不用
- 如何设计成一个资源
