HTTP 缓存
首先都知道HTTP缓存都是从第二次请求开始的。
- 第一次发起请求后,服务器返回资源,并在
response header
中返回带Cache-Control(http1.1)
和Expires(http1.0)
的字段,状态码为200
。 - 第二次发起请求后,强缓存命中则直接读取浏览器缓存,在network中显示的是
from memory
或者from disk
,状态码为200
。当浏览器的强缓存失效的时候或者请求头中设置了不走强缓存,并且在请求头中设置了If-Modified-Since(http1.0)
或者If-None-Match(http1.1)
的时候,会将这两个属性值到服务端去验证是否命中协商缓存,如果命中了协商缓存,会返回304
状态码,加载浏览器缓存,并且响应头会设置Last-Modified
或者ETag
属性。 - 若强缓存和协商缓存都未命中,则服务器返回新的资源。
Q: 怎么设置不走强缓存?
- 请求头设置Cache-Control: no-cache
不会走强缓存了,每次请求都回询问服务端,但不妨碍协商缓存。 - 请求头设置Cache-Control: no-store
会让浏览器、服务器都不缓存,也就没有所谓的强缓存、协商缓存了。
Q: from memory 和 from disk 区别知道吗?
- from memory:一般是 字体、图片文件。(js脚本不一定)
- from disk:一般是 css 文件。
Q: Cache-Control 的 public、 private 区别知道吗?
- public:所有的内容都可以被缓存 ,包括浏览器和代理服务器, 如 CDN。
- private:所有的内容只有浏览器可以缓存,代理服务器不能缓存,是默认值。
HTTP 状态码
讲一些常见的HTTP状态码
- 101: 在
HTTP
升级为WebSocket
的时候,如果服务器同意变更,就会发送状态码 101。 - 200:
OK
成功返回的状态码,有数据会放在响应体。 - 204:
NO Content
成功返回的状态码,但响应头后没有 body 数据。 - 301: Location 永久重定向。
- 302: Location 临时重定向。
- 304:
Not Modified
协商缓存。 - 400:
Bad Request
请求无效。 - 401:
Unauthorized
鉴权失败。 - 403:
Forbidden
禁止访问。 - 404:
Not Found
资源未找到。 - 500: 服务端报错。
Q: 301 和 302 什么区别?
- 301永久重定向是可以缓存的。(可以在
Status Code
后面看到 from disk/memory cache) - 302临时重定向没有缓存。
Q: 重定向会带上原来请求的数据吗?
- 应该是可以带的。(暂定存疑)
HTTP 报文结构
请求报文和响应报文大致上都是起始行
+头部
+空行
+实体
。
-
起始行
请求报文起始行为请求方法
路径
HTTP版本
。
响应报文起始行HTTP版本
状态码
状态
。 -
头部
就是常见的那些请求头响应头字段。 -
空行
区分头部和实体。 -
实体
请求携带的数据或者响应返回的数据。
Q: 头部中间加一个空行会怎么样?
- 空行后面的内容都是实体了。
Q: 常见的请求头、响应头有哪些
- 如下
请求头、响应头
常见的请求头字段:
- Host: 服务端的域名
- Accept、Accept-Encoding、Accept-Language:与服务端的协商字段
- Content-Type:浏览器请求体内容的类型
- Content-Length:实体数据的字节长度。
- Referer:请求的页面来源。
- User-Agent:用户代理,一些厂商、设备、版本等信息。
- Cookie:用户的Cookie信息。
- 还有上面提到的缓存相关字段
常见的响应头字段:
- Access-Control-Allow-Origin:指定哪些网站可以跨域源资源共享。
- Access-Control-Allow-Methods:允许的http请求方法
- Content-Type:服务端响应体内容的类型。
- Content-Length:实体数据的字节长度,如果设置短了数据会丢失,设置长了会导致请求失败。
- Set-Cookie:与请求头中的 Cookie 对应
- 还有上面提到的缓存相关字段
Q: 请求头里的Referer是干什么用的?
- 设置一些防盗链,比如直接在浏览器的地址栏中输入一个资源的URL地址,那么这种请求是不会包含Referer的。
Q: Content-Length是什么的长度?
- 实体的传输字节长度。(实体长度和实体的传输长度是有区别,比如说gzip压缩下,消息实体长度是压缩前的长度,消息实体的传输长度是gzip压缩后的长度)
Q: 知道Transfer-Encoding: chunked这个字段吗?
- 在数据内容不能确定,分块传输场景下使用。(无法在请求或者响应前明确指定Content-Length,所以会被忽略不被发送)
Q: Cookie中有哪些属性?
- Name:Cookie的名称。
- Value: Cookie的值。
- Domain: 指定Cookie的域名。
- Path:指定Cookie所属的路径。(只有匹配上
Domain
和Path
才会附加Cookie) - Expires/Max-Age: 过期时间
- Size:Cookie的大小
- HttpOnly:禁止通过document.cookie等方式拿到Cookie。(缓解XSS攻击)
- Secure: Cookie只能用
https
协议发送给服务器。 - SameSite:可以有效缓解CSRF攻击。
SameSite=None
: 浏览器会在同站请求、跨站请求下继续发送Cookie。
SameSite=Strict
: 限制Cookie不能跨站发送,只在访问相同站点时发送Cookie。
SameSite=Lax
: 跨站请求时,如果是安全的HTTP方法情况会携带Cookie。
Q: 同源和同站的区别是什么?
- 同源:
scheme
://ip/hostname
:port
一样表示同源。 - 同站:
二级域名
.顶级域名
一样表示同站。参考文章
安全
讲一下前端常见的一些安全问题以及怎么去预防。
-
XSS
通过HTML内容攻击
:模板渲染的时通过反射
或者存储
插入脚本。
通过HTML属性攻击
: 提前闭合一些属性,传入攻击代码。
JS代码攻击
:跟通过HTML内容攻击相似。
获取Cookie信息
:利用第三方脚本的document.cookie
偷取。预防措施:
1、Set-Cookie时设置httpOnly标记
,使JS无法获取设置httpOnly的Cookie 。
2、对& < > " '
这些进行转译。
3、服务端设置白名单
进行过滤。
4、响应头设置Content-Security-Policy
,不加载第三方脚本。
Q: HTML属性怎么攻击?
比如上传头像,本来保存的是一段url,然后页面通过<img src=”https://juejin.cn/post/url”>渲染。
但是攻击者可能会传入 ' " onerror="alert('xxx')"'
这样的字符串,这样页面渲染头像的时候就被攻击了。
Q: CSP除了在响应头里面设置,还可以在哪里设置?
可以在HTML里通过meta元素设置。
<meta http-equiv=”Content-Security-Policy” content=”default-src ‘self’;”>
Q:CSP有哪些属性?
CSP属性说明
-
CSRF
首先用户登录受信任网站A且在本地生成了Cookie;
其次在没有退出A网站的时候,点击了一个攻击网站或者恶意链接;
最后攻击者就可以对你在A网站的东西进行操作了。预防措施:
1、验证码
。
2、通过Referer
来检查请求的”源”。
3、服务端Token
校验机制。
4、之前说到Cookie设置的SameSite
。 -
ClickJacking
是一种视觉欺骗的手段,主要是一些类似iframe嵌入、图片覆盖、拖拽等类似方法攻击。
Cookie、Session、Token区别
-
Cookie只是实现Session的一种方案
首先要明白Session和Cookie的主要目的就是为了弥补HTTP的无状态特性。1、用Session只需要在浏览器端保存一个id,实际上大量数据都是保存在服务端。
2、如果全部用Cookie,数据量大的时候浏览器是没有那么多空间的。账户信息全在浏览器端,一旦被劫持全部信息都会泄露。而且每次请求的网络传输数据量也会变大。
3、所以一般使用Session + Cookie方式来保持会话状态。 -
Token是一种认证方式
1、用户登录成功,服务端通过一些参数组成加密生成秘钥返回给用户端。
2、后续再次访问服务端,请求头都要带上这个Token秘钥来校验这个请求。(可以预防CSRF攻击)
浏览器跨域
不同源的请求就会被浏览器认为是跨域。
Q: 你们一般是通过什么方法解决跨域?
- 一般是在node层做代理转发。
Q: 还有什么办法吗?
- 通过script标签,jsonp传个回调函数,但是只支持GET请求。
- 服务端设置CORS。
Q: 知道简单请求和非简单请求吗?
简单请求:
- 请求方法为GET、HEAD、POST;
- 且请求头范围为Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type:只限于三个值
application/x-www-form-urlencoded
、multipart/form-data
、text/plain
。
非简单请求:
- 不是简单请求就是非简单请求。
Q: 知道跨域中的简单请求和非简单请求流程吗?
简单请求会直接发出CORS请求。
- 它会自动在请求头当中,添加一个
Origin
字段,服务器根据这个值,决定是否同意这次请求。 - 如果
Origin
指定的源不在许可范围内,浏览器就会将响应拦截。 - 如果
Origin
指定的源在许可范围内,响应头会多出Access-Control-Allow-Origin
、Access-Control-Allow-Credentials
、Access-Control-Allow-Headers
这几个字段。
非简单请求会在正式通信之前,增加一次OPTIONS请求,称为”预检”请求。
- 服务器收到”预检”请求以后,检查
Origin
、Access-Control-Request-Method
和Access-Control-Request-Headers
字段。 - 如果服务器否定了”预检”请求,浏览器就会将响应拦截。
- 如果确认允许了”预检”请求,会返回带有
Access-Control-Allow-Origin
、Access-Control-Allow-Methods
、Access-Control-Allow-Headers
的响应头字段。后续发起的CORS请求,就跟简单请求一样了。
总结
这是我想到问到的HTTP题目,可能还有遗漏的,但是纰漏大概不是很多。面了1个半小时,有1个小时在聊HTTP这方面的东西,这方面针对的更应该更多是校招生,感觉有点太八股文了。然后因为还是裸面,没有花时间准备面试,所以这里很多东西都忘了导致答的很不流畅。总之问题不大,也就是看个机会,之前面试的八股文也是这么背过来的,总结一波下次避免遇到这些问题再次卡壳就好了。