目录
1 手写一个Ajax
ajax 的核心API - XMLHttpRequest
XMLHttpRequest
function ajax(method, path, data = null) {
const xhr = new XMLHttpRequest() || new ActiveXObject();
xhr.open(method, path, true);
xhr.onreadystatechange = function() {
if(xhr.readystate === 4) {
if(xhr.status === 200) {
console.log(JSON.parse(xhr.responseText));
}
}
}
const data = method.toUpperCase() === 'GET' ? null : JSON.stringify(data);
xhr.send(data);
}
xhr.readystate:
-
0 - UNSET 尚未调用 open 方法
-
1 - OPEND open 方法已被调用
-
2 - HEADERS_RECEIVED send 方法已被调用,header 已被接收
-
3 - LOADING 下载中,responseText 已有部分内容
-
4 - DONE 下载完成
xhr.status:
-
2xx - 表示成功处理请求,如 200
-
3xx - 需要重定向,浏览器直接跳转,如 301 302 304
-
4xx - 客户端请求错误,如 403 404
-
5xx - 服务器端错误
2 什么是同源策略
同源策略(英文全称 Same origin policy)是浏览器提供的一个安全功能。它限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。
简而言之就是浏览器规定,A 网站的 JavaScript,不允许和非同源的网站 C 之间,进行资源的交互。
什么是跨域?
跨域指的是两个 URL 的协议、域名、端口只要其中一个不一致,就会形成跨域。
出现跨域的根本原因 浏览器的同源策略不允许非同源的 URL 之间进行资源的交互。
不过图片、css、js 引入可无视同源策略
只要域名、协议、端口三者相同则为同源。
加载img、css 和js 可无视同源策略,可以通过他们进行跨域。
前端解决跨域问题常见方式为jsonp
因为有同源策略,所以需要进行跨域
跨域的实现方式
JSONP
CORS
JSONP:
-
<script> 可绕过跨域限制
-
服务器可以任意动态拼接数据返回
-
所以,<script> 就可以获得跨域的数据,只要服务端愿意返回
// jQuery 实现 jsonp
$.ajax({
url: 'xxx'
dataType: 'jsonp',
jsonpCallback: 'yyy'
success: function (data) {
console.log(data)
}
})
CORS:
-
服务器设置 http header
什么是同源策略?什么是跨域?如何去解决跨域问题?CORS和JSONP的使用方法_荒古玄枫的博客-CSDN博客
3 手写ajax promise优化版
function ajax(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest() || new ActiveXObject();
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) {
reject(new Error('404 not found'))
}
}
}
xhr.send(null)
})
}
4 常用的ajax工具
jQuery
fetch
axios
Jquery
fetch
fetch返回的promise不会被标记为reject,即使该http响应的状态码是404 或 500。只有网络故障或请求被阻止时才会标记为reject
fetch不会从服务端发出cookie
axios
对 XMLHTTPRequest的封装
5 描述 cookie localStorage sessionStorage 区别
cookie:
-
本身用于浏览器和 server 通讯
-
被“借用”到本地存储来
-
可用 documen.cookie = 'key = value' 来修改,若 key 存在 cookie 则覆盖,否则追加
cookie 的缺点:
-
存储大小,最大 4KB
-
http 请求时需要发送到服务端,增加请求数据量
localStorage 和 sessionStorage:
-
HTML 专门为存储而设计,最大可存 5M
-
API 简单易用 setItem、getItem
-
不会随着 http 请求被发送出去
localStorage 和 sessionStorage区别:
-
localStorage 数据会永久存储,除非代码或手动删除
-
sessionStorage 数据只存在于当前会话,浏览器关闭清空
-
一般用 localStorage 会更多一些
6 http状态码
状态码分类:
1xx 服务器收到请求
2xx 请求 成功,如200 ok
3xx 重定向,如302 Found
4xx 客户端错误,如404
5xx 服务端错误
常见状态码:
200 成功
301 永久重定向(配合location,浏览器自动处理)
302 临时重定向(配合location,浏览器自动处理) !!!重要
304 资源已被请求过且未被修改 not modified
401 Unauthorized当前请求需要用户验证
403 Forbidden 服务器已经收到请求,但拒绝执行 //没有权限
404 Not Found 服务器无法根据用户的请求找到资源//文件不存在或者请求路径有问题
500 服务器错误
504 网关超时
7 什么是 Restful api
传统url是功能
restful的url是一个资源标识
RESTful API就是REST风格的API,即rest是一种架构风格
传统的 methods
get 获取服务器的数据
post 向服务器提交数据
简单的网页功能,就这两个操作
现在的 methods-1
get 获取数据
post 新建数据
patch / put 更新数据
delete 删除数据
Restful api
一种新的 api 设计方法(早已推广使用)
传统 api 设计: 把每个 url 当成一个功能
restful api 设计:把每个 url 当成一个唯一的资源
如何设计成一个资源?
尽量不用 url 参数
传统 api 设计:/api/list?pageIndex=2
restful api 设计:/api/list/2
用 method 表示操作类型
传统 api 设计 post请求
/api/create-blog
/api/update-blog?id=100
传统 api 设计 get请求
/api/get-blog?id=100
restful api 设计
post请求 /api/blog
patch请求 /api/blog/100
get请求 /api/blog/100
这样做的好处就是:
- 项目的分工更加明确了
- 实现了前后端的解耦
- 可以将前端和后端部署到不同的服务器上来减轻服务器的压力
- 前后端代码在不同的服务器上,可以提高安全性
8 http headers
常见的 Request Headers
Accept 浏览器可接受的数据格式
Accept-encoding 浏览器可接受的压缩算法,如gzip(服务器压缩,客户端解压,让传输的资源变小,速度更快)
Accept-Language 浏览器可接收的语言,如zh-CN
Connection:keep-alive 一次TCP连接重复使用
Cookie:同域每次请求资源都会把cookie带上
Host:请求的域名
User-agent:简称UA,浏览器信息,标识是什么浏览器,是什么系统,供给服务器分析
Content-type:发送数据的格式,如application/json(一般get请求是没有的)
常见的 Response Headers
Content-type: 返回数据的格式,如application/json
Content-length: 返回数据的大小,多少字节
Content-Encoding: 返回数据的压缩算法,如gzip
Connection:keep-alive 一次TCP连接重复使用
Set-Cookie: 服务端需要通过该字段来修改浏览器中的cookie
自定义header
别和前面的重复,就可以了。
缓存相关的headers
Cache-Control Expires
last-Modified if-Modified-Since
etag if-None-Match
9 http 缓存
浏览器访问一个新的网站(之前对他一无所知),就会去访问服务端获取数据
但是第二次再访问,有些资源不需要再次去服务器获取,即把不需要重新获取的资源暂存一份
意义:
从输入一个网址到加载页面整个流程,以现代计算机,无论是手机还是电脑,在浏览器、CPU、内存没有问题的情况下,CPU的计算包括页面的渲染师非常快的,可以做到毫秒级
但整个流程中比较慢的环节是网络请求,网络请求受信号影响,所以我们要尽量减少网络请求的体积和数量,使得网络请求更快,页面加载,页面渲染更快
可以被缓存的资源:
-
静态资源(js、css、img)
-
注意:html一般是不能缓存的,因为 html 随时可能被开发人员上线更新、替换模版
-
注意:webpack 打包时可以给静态资源加一个hash,hash是通过资源内容来算的,所以加上hash后缀后,静态资源被打包上线后是不会改变的,除非内容发生变动
http 强制缓存 / http 协商缓存(对比缓存)
Cache-Control:
由服务端控制,若服务端感觉当前资源(如:js、css、img)可以被缓存,则会在 Response Headers 中,添加 Cache-Control
-
Response Headers 中(Request Headers中也存在)
-
控制强制缓存的逻辑(服务端控制)
-
例如:Cache-control: max-age = 31536000 (单位:秒)
Cache-Control 的值:
-
max-age - 缓存最大过期时间
-
no-cache - 不使用强制缓存,正常到服务器请求,不管服务端怎么处理
-
no-store(不常见) - 不使用强制缓存,也不使用服务端的一些缓存措施
-
private - 只允许最终用户做缓存,如手机、电脑、浏览器等
-
public - 允许中间的一些路由或代理也可以做缓存
关于 Expires:
-
同在 Response Headers 中
-
同为控制缓存过期
-
已被 Cache-Control 代替
-
浏览器2种写法,若同时存在,以Cache-Control为主
http 协商缓存(对比缓存)
-
服务器端缓存策略(是一个策略,由服务端判断改文件是不是可以被缓存,而不是缓存在服务端)
-
服务器判断客户端资源,是否和服务端资源一样
-
一致则返回 304,但不返回资源,否则返回 200 和最新的资源
资源标识:
-
在 Response Headers 中,有两种
-
Last-Modified - 资源的最后修改时间
-
Etag - 资源的唯一标识(一个字符串,类似人类的指纹)
-
注意:发送请求时 Last-modified 以 If-Modified-Sence 在 Request Headers 中发送到服务器
-
注意:发送请求时 Etag 以 If-None-Match 在 Request Headers 中发送到服务器
Last-Modified 和 Etag:
-
会优先使用 Etag
-
Last-Modified 只能精确到秒级(相比计算机的毫秒级计算,还是非常宽泛的)
-
如果资源被重复生成,而内容不变,则 Etag 更精确
首次返回和再次请求 Headers 示例:
返回 第二次请求
首次请求和再次请求 资源大小 示例:
总结:
-
首次请求,服务器返回:状态码 200、请求资源、缓存信息(Cache-Control、Last-Modified、Etag)、...
-
再次请求,请求头携带 Cache-Control、If-Modified-Sence、If-None-Match,发现有缓存,根据Cache-Control中max-age判断缓存是否过期,没有过期,则返回:状态码 304,读取本地缓存资源(强制缓存)
-
Cache-Control过期,则判断请求头中是否有If-Modified-Sence、If-None-Match,没有则等同首次请求
-
有If-Modified-Sence、If-None-Match,且服务器判断缓存不可用,则等同首次请求返回
-
若服务器判断缓存可用,则返回:状态码 304,读取本地缓存资源(协商缓存)
刷洗操作对缓存的影响:
-
正常操作:强制缓存有效,协商缓存有效(地址栏输入url, 跳转连接,前进后退等)
-
手动刷新:强制缓存失效,协商缓存有效(F5, 点击刷新按钮,右击菜单刷新)
-
强制刷新:强制缓存失效,协商缓存失效(ctrl + F5)
10 http加密
https 加密方式
http 和 https 区别
http 是明文传输,敏感信息容易被中间劫持
https = http + 加密,劫持了也无法解密
现代浏览器已经开始强制 https 协议
加密方式: 对称加密,非对称加密
对称加密:一个 key 同负责加密解密
非对称加密: 一对key, a 加密之后, 只能用 b 来解密
https 同时用到了这两种加密方式
-
对称加密:利用同一个key加密解密(不安全)
-
非对称加密:A加密后,只能用B解密(安全,B无法被劫持)
https 证书 解决中间人攻击
-中间人攻击(如果传输过程中,pubkey被人掉包
-使用第三方证书(慎用免费、不合规的证书)
-浏览器校验证书
11 http 面试题 - 总结
http 状态码
http method
restful api
http headers
http 缓存策略
常见的 HTTP 请求类型:
GET,表示向服务器获取资源
POST,表示向服务器提交信息,通常用于产生新的数据,比如注册
PUT,表示希望修改服务器的数据,通常用于修改
DELETE,表示希望删除服务器的数据
OPTIONS,发生在跨域的预检请求中,表示客户端向服务器申请跨域提交
TRACE,回显服务器收到的请求,主要用于测试和诊断
CONNECT,用于建立连接管道,通常在代理场景中使用,网页中很少用到
在我大万维网世界中
TCP就像汽车,我们用TCP来运输数据,它很可靠,从来不会发生丢件少件的现象。但是如果路上跑的全是看起来一模一样的汽车,那这个世界看起来是一团混乱,送急件的汽车可能被前面满载货物的汽车拦堵在路上,整个交通系统一定会瘫痪。为了避免这种情况发生,交通规则HTTP诞生了。HTTP给汽车运输设定了好几个服务类别,有GET, POST, PUT, DELETE等等,HTTP规定,当执行GET请求的时候,要给汽车贴上GET的标签(设置method为GET),而且要求把传送的数据放在车顶上(url中)以方便记录。如果是POST请求,就要在车上贴上POST的标签,并把货物放在车厢里。当然,你也可以在GET的时候往车厢内偷偷藏点货物,但是这是很不光彩;也可以在POST的时候在车顶上也放一些数据,让人觉得傻乎乎的。HTTP只是个行为准则,而TCP才是
GET和POST怎么实现的基本。
常见的 HTTP 请求类型_Just-ForStudy的博客-CSDN博客_请求类型
HTTP请求方法GET与POST的本质区别_KarenChia的博客-CSDN博客_http请求本质
HTTP和HTTPS区别:
- http 协议是免费使用的,而 https 协议需要到CA机构申请证书,需要缴纳费用
- http 是超文本传输协议,信息是明文传输,https 则是具有安全性的 ssl/tls 加密传输协议,信息是密文
- http 的连接很简单,是无状态的;https 协议是由SSL/TLS+HTTP协议构建的可进行加密传输、身份认证的网络协议,比 http 协议安全
- 和 http 通信相比,https 通信会由于加减密处理消耗更多的CPU和内存资源
- http 和 https 使用的端口也不一样,前者是80,后者是443
GET和POST区别和应用:
实际开发中会产生各种区别,主要是因为浏览器的默认行为造成的。
在实际开发中,GET 和 POST 有以下区别:
- 浏览器在发送 GET 请求时,不会附带请求体
- GET 请求的传递信息量有限,适合传递少量数据;POST 请求的传递信息量是没有限制的,适合传输大量数据。
- GET 请求只能传递 ASCII 数据,遇到非 ASCII 数据需要进行编码;POST 请求没有限制
- 大部分 GET 请求传递的数据都附带在 path 参数中,能够通过分享地址完整的重现页面,但同时也暴露了数据,若有敏感数据传递,不应该使用 GET 请求,至少不应该放到 path 中
- 刷新页面时,若当前的页面是通过 POST 请求得到的,则浏览器会提示用户是否重新提交。若是 GET 请求得到的页面则没有提示。
- GET 请求的地址可以被保存为浏览器书签,POST 不可以
从 http 协议的角度来说,GET 和 POST 它们都只是请求行中的第一个单词,除了语义不同,其实没有本质的区别
URL和URI区别:
URL,统一资源定位符,URL 其实就是我们平时上网时输入的网址,它标识一个互联网资源,并指定对其进行操作或获取该资源的方法。标识一个特定资源并表示该资源的某种形式是可以通过 HTTP 协议从相应位置获得。
URI,统一资源标识符,URL 是 URI 的一个子集,简单地说,只要能唯一标识资源的就是 URI
URI表示的是一个抽象的地址,URL表示的是一个详细的地址。
抽象的地址:浙江省杭州市(这是一个抽象的地址,相当于URI)
详细的地址:浙江省杭州市高新园区软件园B2(这是一个详细的地址,相当于URL)
websocket是什么:
WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
Ajax 轮询,轮询是在特定的的时间间隔(如每1秒)浪费很多的带宽等资源。
HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
websocket 的 工作原理:
WebSocket 协议本质上是一个基于 TCP 的协议。
为了建立一个 WebSocket 连接,客户端浏览器首先要向服务器发起一个 HTTP 请求,这个请求和通常的 HTTP 请求不同,包含了一些附加头信息,其中附加头信息"Upgrade: WebSocket"表明这是一个申请协议升级的 HTTP 请求,服务器端解析这些附加的头信息然后产生应答信息返回给客户端,客户端和服务器端的 WebSocket 连接就建立起来了,双方就可以通过这个连接通道自由的传递信息,并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接。
DNS解析过程
- 浏览器搜索自己浏览器的DNS缓存
- 若没有,则搜索本地操作系统中的DNS缓存和hosts文件
- 若没有,则操作系统将域名发送至本地域名服务器,本地域名服务器查询自己的DNS缓存,查找成功则返回结果,否则依次向根域名服务器、顶级域名服务器、权限域名服务器发起查询请求,最终返回IP地址给本地域名服务器
- 本地域名服务器将得到的IP地址返回给操作系统,同时自己也将IP地址缓存起来
- 操作系统将 IP 地址返回给浏览器,同时自己也将IP地址缓存起来
- 浏览器得到域名对应的IP地址
2022年计算机网络热门面试题(附标准答案)_Coder Xu的博客-CSDN博客_计算机网络面试题及答案
HTTP请求转发和重定向的区别