一、HTML面试题
1. 对 HTML 语义化的理解
- 让人更容易读懂(增加代码可读性)。
- 让搜索引擎更容易读懂 (搜索引擎优化:SEO)。
常见的语义化标签:
<header></header> 头部 <nav></nav> 导航栏 <section></section> 区块(有语义化的div) <main></main> 主要区域 <article></article> 主要内容 <aside></aside> 侧边栏 <footer></footer> 底部
2. 默认情况下,哪些是块级元素、哪些是行内块元素、哪些是行内元素?
2.1 块级元素:
- display: block/table; 有 div、h1~h6、table、form、ul、ol、dl、p 等。
2.2 行内块元素:
- display: inline-block; 有 img、input、button、select、textarea 等。
2.3 行内元素:
- display: inline; 有 a、span、strong、b、em、i、label、br 等。
2.4 区别:
类别 是否独占一行 能否设置宽高 能否设置margin 能否设置padding 块级元素 是 能 能 能 行内块元素 否 能 能 能 行内元素 否 否 仅左右有效 能
HTML面试题详解链接:HTML面试题-CSDN博客。
二、CSS面试题
1. 盒模型宽度计算
- offsetWidth = ( 内容宽度 + 内边距 + 边框 ),无外边距。
- 这里的offsetWidth是 122px。
- 如果让 offsetWidth 等于 100px ,该如何做?
- 添加: box-sizing: border-box;
2. margin 纵向重叠问题
- 相邻元素的 margin-top 和 margin-bottom 会发生重叠,取两者的最大值作为它们之间的距离。
- 空白内容的 <p></p> 也会重叠。
3. margin 负值问题
- margin-top 和 margin-left 负值,不会增加元素高度和宽度,元素向上、向左移动。
- margin-right 设置负值不会产生位移,只会减小元素供CSS读取的宽度。
- margin-bottom 设置负值不会产生位移,只会减小元素供CSS读取的高度。
- 在元素没有设定width属性或width:auto时,设置左右margin负值会增加元素的宽度 。
4. BFC 的理解和应用
4.1 什么是 BFC?如何应用?
- Block format context ,块级格式化上下文。
- 一块独立渲染区域,内部元素的渲染不会影响边界以外的元素。
4.2 形成 BFC 的常见条件
- float 不是 none。
- position 是 absolute 或 fixed。
- overflow 不是 visible。
- display 是 flex inline-block 等。
4.3 BFC 的常见应用
- 清除浮动
- 解决margin的重叠问题
5. float 布局的问题,及clearfix
5.1 圣杯布局:
- 利用浮动和负边距来实现。
- 父级元素设置左右的 padding,三列均设置向左浮动。
- 中间一列放在最前面,宽度设置为父级元素的宽度,因此后面两列都被挤到了下一行。
- 通过设置 margin 负值将其移动到上一行,再利用相对定位,定位到两边。
.outer { height: 100px; padding-left: 100px; padding-right: 200px; } .left { position: relative; left: -100px; float: left; margin-left: -100%; width: 100px; height: 100px; background: tomato; } .right { position: relative; left: 200px; float: right; margin-left: -200px; width: 200px; height: 100px; background: gold; } .center { float: left; width: 100%; height: 100px; background: lightgreen; }
5.2 双飞翼布局:
- 双飞翼布局相对于圣杯布局来说,左右位置的保留是通过中间列的 margin 值来实现的。
- 而不是通过父元素的 padding 来实现的。本质上来说,也是通过浮动和外边距负值来实现的。
.outer { height: 100px; } .left { float: left; margin-left: -100%; width: 100px; height: 100px; background: tomato; } .right { float: left; margin-left: -200px; width: 200px; height: 100px; background: gold; } .wrapper { float: left; width: 100%; height: 100px; background: lightgreen; } .center { margin-left: 100px; margin-right: 200px; height: 100px; }
5.3 圣杯布局和双飞翼布局的技术总结
- 使用 float 布局。
- 两侧使用 margin 负值,以便和中间内容横向重叠。
- 防止中间内容被两侧覆盖,圣杯布局在父元素设置 padding,双飞翼布局在center上设置 margin。
5.4 手写 clearfix
/* 手写 clearfix */ .clearfix:after { content: ''; display: table; clear: both; } .clearfix { /* 兼容 IE 低版本 */ *zoom: 1; }
6. flex 画色子
6.1 常用语法
- 容器属性:flex-direction(决定主轴的方向)、justify-content(主轴上的对齐)、flex-wrap(是否换行)、align-items(交叉轴上如何对齐)。
- 项目属性:align-self(该项目在交叉轴的对齐方式)。
- 详细介绍地址:flex布局--入门_小豪boy的博客-CSDN博客。
6.2 flex 实现一个三点的色子
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>flex 画骰子</title> <style> .box { width: 200px; height: 200px; border: 2px solid #ccc; border-radius: 10px; padding: 20px; /* flex 布局 */ display: flex; /* 两端对齐 */ justify-content: space-between; } .item { /* 点的样式 */ display: block; width: 40px; height: 40px; border-radius: 50%; background-color: #666; } .item:nth-child(2) { /* 第二项居中对齐 */ align-self: center; } .item:nth-child(3) { /* 第三项尾对齐 */ align-self: flex-end; } </style> </head> <body> <div class="box"> <span class="item"></span> <span class="item"></span> <span class="item"></span> </div> </body> </html>
7. absolute 和 relative 分别依据什么进行定位?
- relative 依据自身定位。
- absolute 依据最近一层的定位元素定位。
- 定位元素:
- absolute relative fixed
- body
8. 居中对齐有哪些实现方式?
8.1 水平居中
文本水平居中:
- 文本内容居中:text-align: center;
div水平居中:
- 有固定宽度:margin: 0 auto;
- absolute 定位,知道元素宽度:left: 50% ;margin-left:负宽度的一半;
- absolute 定位,元素宽度未知:left: 50%;transform:translateX(-50%);
- absolute 定位:left: 0; right: 0; margin: 0 auto;
- flex布局:justify-content: center;
8.2 垂直居中
文本垂直居中:
- 设置行高等于所在区域的高度:height: 200px; line-height: 200px;
- vertical-align实现文本的垂直居中:display:table-cell; vertical-align:middle;
div垂直居中:
- absolute 定位,知道元素高度:top: 50%;margin-top:负高度的一半;
- absolute 定位,元素高度未知:top: 50%;transform: translateY(-50%);
- absolute 定位:top: 0; bottom: 0; margin: auto 0;
- flex布局:align-items:center;
8.3 水平垂直居中
文本水平垂直居中:
- text-align: center;height: 200px; line-height: 200px;
- text-align: center;display:table-cell; vertical-align:middle;
div水平垂直居中:
- absolute 定位,知道元素宽高:left: 50% ;margin-left:负宽度的一半;top: 50%;margin-top:负高度的一半;
- absolute 定位,元素宽高未知:left: 50%; top: 50%;transform: translate(-50%,-50%);
- absolute 定位:left: 0; right: 0; top: 0; bottom: 0; margin: auto;
- flex布局:justify-content: center; align-items:center;
9. line-height 的继承问题
- 带单位:px 是固定值,而 em 会参考父元素 font-size 值计算自身的行高
- 纯数字:会把比例传递给后代。例如,父级行高为 1.5,子元素字体为 18px,则子元素行高为 1.5 * 18 = 27px
- 百分比:将计算后的值传递给后代
10. rem 是什么?
- rem 是一个长度单位。
- em ,相对长度单位,相对于父元素,不常用。
- px ,绝对长度单位,最常用。
- rem ,相对长度单位,相对于根元素,常用于响应式布局。
11. 如何实现响应式?
- media-query,根据不同的屏幕宽度设置根元素 font-size。
- rem,基于根元素的相对单位。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>响应式布局</title> <style> @media only screen and (max-width: 374px) { /* iphone5 或者更小的尺寸,以 iphone5 的宽度(320px)比例设置 font-size */ html { font-size: 86px; } } @media only screen and (min-width: 375px) and (max-width: 413px) { /* iphone6/7/8 和 iphone x */ html { font-size: 100px; } } @media only screen and (min-width: 414px) { /* iphone6p 或者更大的尺寸,以 iphone6p 的宽度(414px)比例设置 font-size */ html { font-size: 110px; } } body { font-size: 0.16rem; } #div1 { width: 1rem; height: 1rem; background-color: gold; } </style> </head> <body> <div id="div1"></div> </body> </html>
CSS面试题详解链接:CSS面试题-CSDN博客。
三、JavaScript面试题
1. JavaScript有哪些数据类型?
- JavaScript共有八种数据类型,分别是 Undefined、Null、Boolean、Number、String、Object、Symbol、BigInt。
- 其中 Symbol 和 BigInt 是ES6 中新增的数据类型。
- 基本数据类型(值类型):Undefined、Null、Boolean、Number、String、Symbol、BigInt,除了
null
和undefined
之外,所有基本类型都有其对应的包装对象。- 引用类型(对象):Object。
2. typeof 能判断哪些类型?
console.log(typeof 2); // number console.log(typeof true); // boolean console.log(typeof 'str'); // string console.log(typeof []); // object console.log(typeof function(){}); // function console.log(typeof {}); // object console.log(typeof undefined); // undefined console.log(typeof null); // object
- 其中数组、对象、null都会被判断为object,其他判断都正确。
3. 何时使用 === 何时使用 == ?
4. 值类型和引用类型的区别?
- 声明变量时不同的内存分配:栈与堆。
- 不同的访问机制:直接访问与引用访问。
- 复制变量时不同:直接复制值与复制内存地址。
- 参数传递的不同:传递值和传递内存地址。
5. 手写深拷贝
- 判断值类型和引用类型。
- 判断是数组还是对象。
- 判断 key 是不是原型的属性
- 递归。
/** * 深拷贝 * @param {Object} obj 要拷贝的对象 */ function deepClone(obj = {}) { if (typeof obj !== 'object' || obj == null) { // obj 是 null ,或者不是对象和数组,直接返回 return obj } // 初始化返回结果 let result if (obj instanceof Array) { result = [] } else { result = {} } for (let key in obj) { // 保证 key 不是原型的属性 if (obj.hasOwnProperty(key)) { // 递归调用!!! result[key] = deepClone(obj[key]) } } // 返回结果 return result }
6. 如何准确判断一个变量是不是数组?
instanceof
可以正确判断对象的类型,其内部运行机制是判断在其原型链中能否找到该类型的原型。console.log(2 instanceof Number); // false console.log(true instanceof Boolean); // false console.log('str' instanceof String); // false console.log([] instanceof Array); // true console.log(function(){} instanceof Function); // true console.log({} instanceof Object); // true
- 可以看到,
instanceof
只能正确判断引用数据类型,而不能判断基本数据类型。
7. class 的原型本质,怎么理解?
- class 是ES6语法规范,实际上是函数,可见是语法糖,具体实现还是使用的原型与原型链。
- 隐世原型(__proto__)和显示原型(prototype)。
- 每个 class都有显示原型 prototype。
- 每个实例都有隐式原型 __proto__。
- 实例的 __proto__ 指向对应 class 的 prototype 。
原型链:
- 获取实例的属性或执行方法时,先在自身属性和方法中寻找,如果找不到则自动去隐式原型 __proto__ 中查找,若还是没有找到,则逐级向上查找,当查找到目标或隐式原型 __proto__ 为 null 时,结束查找。
8. 手写一个简易的 JQuery 考虑插件和扩展性
- 简易的jQuery
class jQuery { constructor(selector) { const result = document.querySelectorAll(selector) const length = result.length for (let i = 0; i < length; i++) { this[i] = result[i] } this.length = length this.selector = selector } get(index) { return this[index] } each(fn) { for (let i = 0; i< this.length; i++) { const elem = this[i] fn(elem) } } on(type, fn) { return this.each(elem => { elem.addEventListener(type, fn, false) }) } }
- 插件
// 插件 jQuery.prototype.dialog = function (info) { alert(info) }
- 扩展性--“造轮子”
// “造轮子” class myJQuery extends jQuery { constructor(selector) { super(selector) } // 扩展自己的方法 addClass(className) { } style(data) { } }
9. this 的不同应用场景,如何取值?
10. 手写 bind 函数
// 模拟 bind Function.prototype.bind1 = function () { // 将参数拆解为数组 const args = Array.prototype.slice.call(arguments) // 获取 this (数组的第一项,数组剩余的就是传递的参数) const t = args.shift() // fn1.bind(...) 中的 fn1 const self = this // 返回一个函数 return function () { // 执行原函数,并返回结果 return self.apply(t, args) } }
11. 实际开发中闭包的应用场景,举例说明
- 做一个简单的 cache 隐藏工具
// 闭包隐藏数据,只提供 API function createCache() { // 闭包中的数据,被隐藏,不被外界访问 const data = {} return { set: function (key, val) { data[key] = val }, get: function (key) { return data[key] } } }
12. 创建 10 个 a 标签,点击的时候弹出对应的序号
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial=1.0"> <title>作用域</title> </head> <body> <script> // 创建 10 个 <a> ,在块级作用域中,声明序号 i ,点击时弹出来的序号与标签中的序号对应。 let a for (let i = 0; i < 10; i++) { a = document.createElement('a') a.innerHTML = i + '<br>' a.addEventListener('click', (e) => { e.preventDefault console.log(i) }) document.body.appendChild(a) } </script> </body> </html>
13. 同步和异步的区别是什么?
- 异步不会阻塞代码执行。
- 同步会阻塞代码执行。
14. 手写用 Promise 加载一张图片
// 异步加载图片。 function loadImg(src) { const p = new Promise( (resolve, reject) => { const img = document.createElement('img') img.onload = () => { resolve(img) } img.onerror = () => { const err = new Error(`图片加载失败 ${src}`) reject(err) } img.src = src } ) return p }
15. 前端使用异步的场景有哪些?
- 网络请求,如 ajax 图片加载。
- 定时任务,如 setTimeout。
16. 请描述 event loop(事件循环/事件轮询)的机制,可画图
- 同步代码,一行一行放在 Call Stack 执行。
- 遇到异步,会先 “记录” 下,等待时机(定时、网络请求等)。
- 时机到了,就移动到 Callback Queue。
- 同步代码执行完 Call Stack 为空,Event Loop 开始工作。
- 轮询查找 Callback Queue,如有则移动到 Call Stack 执行。
- 然后继续轮询查找(永动机一样)。
17. 什么是宏任务和微任务,两者有什么区别?
- 宏任务:DOM渲染后触发,setTimeout,setInterval,Ajax,DOM事件。
- 微任务:DOM渲染前触发,Promise,async/await。
- 微任务执行时机比宏任务要早。
18. Promise有哪三种状态?如何变化?
- Promise 有 3 种状态,一开始是 pending(未完成)。
- 执行 resolve,变成 fulfilled(resolved),已成功。
- 执行 reject,变成 rejected,已失败。
19. then 和 catch 的链式调用题目
- Promise 的实例化为同步部分会立即执行,后面的 then 和 catch 才进行异步处理
20. async/await是什么
- async/await 是同步语法,彻底消灭回调函数。
- 本质上只是一个语法糖,具体实现还是得有异步,还是得基于 event loop。
- async是一个加在函数前的修饰符,被async定义的函数会默认返回一个Promise对象resolve的值。
- await 操作符用于等待一个 Promise 对象,它只能在异步函数 async function 内部使用。
21. async/await 和 Promise 的关系
- 执行 async 函数,返回的是 Promise 对象。
- await相当于 Promise 的 then。
- try- catch可捕获异常,代替了 Promise的 catch。
22. async/await 的执行流程
- 只要遇到了 await,await 本身会立即执行,而 await 后面的代码都相当于放在 callback 里,进行异步处理。
async function async1() { console.log('async1 start') // 2 await async2() // 这一句会同步执行,返回 Promise ,其中的 `console.log('async2')` 也会同步执行 console.log('async1 end') // 5 上面有 await ,下面就变成了“异步”,类似 callback 的功能(微任务) } async function async2() { console.log('async2') // 3 } console.log('script start') // 1 async1() console.log('script end') // 4
async function async1() { console.log('async1 start') // 2 await async2() // 这一句会同步执行,返回 Promise ,其中的 `console.log('async2')` 也会同步执行 // 上面有 await ,下面就变成了“异步”,类似 callback 的功能(微任务) console.log('async1 end') // 6 } async function async2() { console.log('async2') // 3 } console.log('script start') // 1 setTimeout(function () { // 异步,宏任务 console.log('setTimeout') // 8 }, 0) async1() // 初始化 Promise 时,传入的函数会立刻被执行 new Promise(function (resolve) { // 返回 Promise 之后,即同步执行完成,then 是异步代码 console.log('promise1') // 4 resolve() }).then(function () { // 异步,微任务 console.log('promise2') // 7 }) console.log('script end') // 5 // 同步代码执行完,(event loop - call stack 被清空) // 执行微任务 // (尝试触发 DOM 渲染) // 触发 Event Loop,执行宏任务
23.for of 与 for in的区别
for of :
- 遍历可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等等)。
- 在每次迭代时,得到的是不同属性的值(value)。
- 不能遍历对象。
for in:
- 遍历一个对象(包含数组)。
- 在每次迭代时,得到的是不同属性的键名(key)。
JS面试题详解链接:
补充:
JS Web API:
- DOM:文档对象模型,处理网页内容的方法和接口。
- BOM:浏览器对象模型,与浏览器交互的方法和接口。
- 事件:视图层到逻辑层的通讯方式。
- ajax:异步的 JavaScript 和 XML,是一种用于创建快速动态网页的技术。
- 存储:本地存储。
四、DOM 题目
1. DOM是哪种数据结构
- DOM是JS操控HTML和CSS的桥梁。
- DOM是哪种基本的数据结构? —— 树。
2. DOM操作的常用API
2.1 节点操作:
2.2 结构操作:
- 添加新节点:创建新节点,向 DOM 树上的节点插入新节点。
- 移动节点:将已经挂载到DOM树上的节点成为appendChild()的参数,这个节点将会被移动。
- 获取父节点
- 获取子元素节点(childNodes会获取所有的子节点,其中可能包括很多元素节点之外的其他节点)
- 删除子节点
3. attribute 和 property的区别
attribute 是 dom 元素在⽂档中作为 html 标签拥有的属性;
property 就是 dom 元素在 js 中作为对象拥有的属性。
对于 html 的标准属性来说,attribute 和 property 是同步的,是会⾃动更新的。
但是对于⾃定义的属性来说,他们是不同步的。
4. 一次性插入多个 DOM 节点,考虑性能
- 关键在于创建一个文档片段:document.createDocumentFragment()。
DOM 面试题详解链接:JS-Web-API-DOM面试题-CSDN博客。
五、BOM 题目
1. 如何识别浏览器的类型
2. 分析拆解url 各个部分
BOM 面试题详解链接:JS-Web-API-BOM面试题-CSDN博客。
六、事件题目
1. 编写一个通用的事件监听函数
注:
- selector: 是个css选择器字符串。
- target.matches(selector) : 如果元素被指定的选择器(selector)字符串选择返回true; 否则返回false。
2. 描述事件冒泡的流程
- 基于 DOM 树形结构。
- 事件会顺着触发元素向上冒泡。
- 应用场景:代理。
3. 无限下拉的图片列表,如何监听每个图片的点击?
- 事件代理又叫事件委托,原理是利用事件冒泡机制,将后代元素事件委托给祖先元素。
- 当有大量类似元素需要批量添加事件监听时,使用事件委托可以减少内存开销。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>事件代理</title> </head> <body> <div id="div3"> <a href="#">a1</a><br> <a href="#">a2</a><br> <a href="#">a3</a><br> <a href="#">a4</a><br> <button>加载更多...</button> </div> <script> // 通用事件绑定函数 function bindEvent(elem, type, selector, fn) { // 处理只传3个参数的情况 if (fn == null) { fn = selector selector = null } elem.addEventListener(type, event => { const target = event.target if (selector) { // 代理绑定 if (target.matches(selector)) { fn.call(target, event) } } else { // 普通绑定 fn.call(target, event) } }) } // 代理绑定 const div3 = document.getElementById('div3') bindEvent(div3, 'click', 'a', function (event) { event.preventDefault() // 阻止默认行为 alert(this.innerHTML) }) </script> </body> </html>
事件面试题详解链接:JS-Web-API-事件-面试题-CSDN博客。
七、ajax 题目
1. 手写一个简易的 ajax
- 创建 xhr 对象
- 准备发送请求
- 监听事件,处理响应
- 发送请求
function ajax(url) { const p = new Promise((resolve, reject) => { const xhr = new XMLHttpRequest() xhr.open('GEt', url, true) xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { resolve( JSON.parse(xhr.responseText) ) } else if (xhr.status === 404 || xhr.status === 500) { reject(new Error('404 not found')) } } } xhr.send(null) }) return p }
2. 跨域的常用实现方式
- ① CORS 跨域资源共享
- ② JSONP
优先使用 CORS 跨域资源共享,如果浏览器不支持 CORS 的话,再使用 JSONP。
ajax 面试题详解链接:JS-Web-API-Ajax-面试题-CSDN博客。
八、存储题目
1. 描述 cookie localStorage sessionStorage区别
- 容量 :cookie(<4K),localStorage 和 sessionStorage(<5M)。
- API易用性:cookie(document.cookie),localStorage 和 sessionStorage(setitem getitem)。
- 是否跟随http请求发送出去:cookie(跟随),localStorage 和 sessionStorage(不跟随)。
- 存储时间:cookie 和 localStorage 数据只存在于当前会话,浏览器关闭则清空;localStorage 数据会永久存储,除非代码或手动删除。
存储面试题详解链接:JS-Web-API-存储-面试题-CSDN博客
九、页面加载过程+性能优化+安全题目
1. 从输入 url 到渲染出页面的整个过程
- 下载资源:各个资源类型,下载过程。
- 渲染页面:
- 根据 HTML 代码生成 DOM Tree 。
- 根据 CSS 代码生成 CSSOM 。
- 将 DOM Tree 和 CSSOM 整合形成 Render Tree 。
- 根据 Render Tree 渲染页面 。
- 遇到 <script> 则暂停渲染,优先加载并执行 JS 代码,完成再继续。
- 直至把 Render Tree 渲染完成。
2. load和 DOMContentLoaded 的区别
- load:资源全部加载完才能执行,包括图片。
- DOMContentLoaded:DOM 渲染完成即可,图片可能尚未下载。
3. 前端常见性能优化方案
3.1 让加载更快
- 减少资源体积:压缩代码。
- 减少访问次数∶合并代码、SSR服务器端渲染、緩存。
- 使用更快的网络:CDN。
3.2 让渲染更快
- CSS 放在 head,JS 放在 body 最下面。
- 尽早开始执行JS,用 DOMContentloaded 触发。
- 懒加载(图片懒加载,上滑加载更多)。
- 对 DOM 查询进行缓存。
- 频繁 DOM 操作,合并到一起插入 DOM 结构。
4. 手写节流和防抖
- 防抖:
// 防抖 function debounce(fn, delay = 500) { // timer 是闭包中的 let timer = null return function () { if (timer) { clearTimeout(timer) } timer = setTimeout(() => { fn.apply(this, arguments) timer = null }, delay) } }
- 节流:
// 节流 function throttle(fn, delay = 100) { // timer 是闭包中的 let timer = null return function () { if (timer) { return } timer = setTimeout(() => { fn.apply(this, arguments) timer = null }, delay) } }
5. Web前端常见的安全攻击方式和预防
5.1 攻击方式
XSS 跨站请求攻击
XSRF/CSRF 跨站请求伪造
5.2 预防
- XSS 预防:替换特殊字符串
- XSRF/CSRF 预防:使用 post 接口、增加验证,如:密码、短信验证码等。
页面加载过程+性能优化+安全面试题详解链接:小豪boy的博客。
十、http 题目
1. http 常见的状态码有哪些?
1xx 服务器收到请求;
2xx 请求成功;
- 200 成功。
3xx 重定向;
- 301 永久重定向(配合 location,浏览器自动处理)。
- 302 临时重定向(配合 location,浏览器自动处理)。
- 304 资源未被修改。
4xx 客户端错误;
- 404 资源未找到。
- 403 没有权限。
5xx 服务器错误;
- 500 服务器错误。
- 504 网关超时。
2. http 常见的 header 有哪些?
2.1 Request Headers
2.2 Responce Headers
3. http methods
- get 获取数据
- post 新建数据
- patch/put 更新数据
- delete 删除数据
4. 什么是 Restful API
- 传统 API 设计:把每个 url 当作一个功能。
- Restful API 设计:把每个 url 当作一个唯一的资源。
如何设计成一个资源?
- 尽量不用 url 参数。
- 用 method 表示操作类型。
5. 描述以下 http 的缓存机制
5.1 强制缓存:
- 强制缓存在缓存数据未失效的情况下(即Cache-Control的max-age没有过期或者Expires的缓存时间没有过期),那么就会直接使用浏览器的缓存数据,不会再向服务器发送任何请求。
5.2 协商缓存(对比缓存):
- 服务器判断客户端资源,是否和服务器端资源一样。
- 一致则返回 304,否则返回 200 和最新资源。
5.3 http 缓存流程图