HTTP:什么是队头阻塞以及怎么解决?
队头阻塞(Head-of-Line Blocking)
计算机网络中的一个概念,特别是在处理HTTP请求时。当多个HTTP请求被发送到一个服务器,并且这些请求被放置在一个队列中等待处理时,如果队列中的第一个请求(队头)由于某种原因(如处理时间长、等待资源等)被阻塞或延迟,那么队列中后面的所有请求都必须等待,即使它们可能不需要等待或可以被更快地处理。这种情况就被称为队头阻塞。
队头阻塞会导致网络性能和响应时间的降低,因为即使后续请求可以更快地被处理,它们也必须等待队头请求完成。
为了解决队头阻塞问题,有几种常见的方法:
- HTTP/2多路复用:HTTP/2通过使用多路复用(multiplexing)技术,允许在一个单一的TCP连接上并行处理多个请求和响应,从而避免了队头阻塞。HTTP/2将请求和响应拆分为更小的帧,并按优先级在TCP连接上进行交错发送。这样,即使某些帧被阻塞,其他帧也可以继续流动。
- 使用多个连接:在某些情况下,可以通过建立多个并行连接来绕过队头阻塞。例如,浏览器可以同时对一个网站的不同资源使用多个HTTP连接。但是,这种方法可能会增加连接建立和管理的开销,并且可能受到浏览器或服务器的限制。
- 优化请求顺序:虽然这不能从根本上解决队头阻塞问题,但优化请求的顺序(例如,先发送重要的或预计处理时间短的请求)可以减少其影响。
- 使用优先级队列:在某些情况下,可以使用优先级队列来管理请求,以便高优先级的请求可以优先得到处理。然而,这需要在服务器或中间件中实现复杂的逻辑。
总的来说,HTTP/2的多路复用是解决队头阻塞问题的最有效方法之一,因为它从根本上改变了请求和响应在TCP连接上的处理方式。
XSS 攻击是什么 ?
XSS 是跨站脚本攻击, Cross-site scripting 缩写。全称缩写后应是 CSS,但这样就和层叠样式表 Cascading Style Sheets 的缩写相同了,为以示区分,改用 XSS。
XSS本质是代码注入。通过某种方式在受攻击网站中注入一些恶意代码,当用户访问该网站去触发这段脚本。
XSS攻击有哪几种类型?
常见的XSS攻击有三种:反射型XSS攻击、DOM-based型XSS攻击、存储型XSS攻击。
反射型 XSS
- 有些网页会将 url 中的一些数据作为渲染的内容去渲染。
- 比如我们希望用户支付完订单后跳转到一个结果页,这个页面通过 url 中的 query 字符串来显示一些内容,比如http://a.com/order?message=成功 ,我们会读取 message 的值 “成功”,将这个文案渲染到页面上。
- 如果这个 “成功” 被黑客替换为恶意脚本,变成 http://a.com/order?message=<script>// 恶意脚本内容</script>,且网站没做转义处理,那这个恶意脚本就会被嵌入执行。
- 当然这个链接很奇怪,用户在常规情况下无法访问到这样的链接。
- 所以攻击者就需要先组装好,然后通过一些方式诱导用户去访问它,比如通过钓鱼邮件诱导点击。
存储型 XSS
- 恶意脚本被持久化保存在数据库中。
- 比如在自己的个人介绍的文本内容中,使用了 <script>// 这里是一些恶意代码</script>。当用户访问攻击者的个人主页时,如果服务端渲染时就会用上这段数据,没有做特别的转义处理,渲染出来的 HTML 中就带上了这个脚本,然后执行。
DOM 型 XSS
- DOM 型 XSS 和反射型有点类似,但它和后端无关,是前端的问题。
- 前面两种类型做的是后端渲染,即用户请求 HTML 时,在服务端拼装返回完整的 HTML 返回。
- DOM 型 XSS 是服务端没有返回完整的 HTML,而是让前端做拼装渲染,如果没有做特殊处理,也会导致恶意代码注入。
XSS 防御
- 不要相信用户的数据;
- 使用转义,常见的是将 "'&<> 做转义。比如 React 对字符做了防 XSS 处理。源码在这里:https://github.com/facebook/react/blob/HEAD/packages/react-dom/src/server/escapeTextForBrowser.js#L51
- 如果做的是后端渲染,也记得做转义处理或过滤处理;
- 使用 CSP(内容安全策略)。Twitter 网站使用了这个;
- 对敏感 cookie 设置 http-only,让前端脚本无法获取到;
- cookie 的 SameSite 属性考虑调整为 Strict 或 Lax,让跨域 HTTP 请求的头字段无法自动携带 cookie;
- 进行敏感请求时,加个验证码校验;
- 控制内容输入长度(作用不大);
总结
- XSS 攻击是一种比较常见的代码注入攻击。
- 在平时写代码时,要注意一些数据进行渲染时,会不会导致 XSS 注入的风险,做一些必要的处理。
POST & GET的区别?
- GET和POST是什么?
- HTTP协议中的两种发送请求的方法,本质上都是在进行TCP连接;
- 功能不同?
- get是从服务器上获取数据。
- post是向服务器传送数据。
- 安全性不同?
- get安全性非常低。
- post安全性较高。
- 因为参数直接暴露在URL中,所以,GET请求不能用来传递敏感信息。
- GET请求在浏览器中可以被主动cache(缓存),而POST请求不会,可以手动设置。
- GET请求参数是通过URL进行传递的,POST请求的参数包含在请求体当中。
- GET请求在url中传递的参数是有长度限制的(在HTTP协议中并没有对URL的长度进行限制,限制是特定的浏览器以及服务器对他的限制,不同浏览器限制的长度不同。),POST对长度没有限制, POST传递的参数在请求。
- GET请求参数会完整的保留在浏览器的历史记录中,POST请求的参数不会保留。
- GET请求进行url编码(百分号编码),POST请求支持多种编码方式。
- GET请求产生的URL地址是可以被bookmark(添加书签)的,POST请求不可以。
- GET请求在浏览器回退的时候是无害的,POST请求会.再次提交数据。
七层网络模型?
在互联网技术里,有两件事最为重要,一个是TCP/IP协议,它是万物互联的事实标准;另一个是Linux操作系统,它是推动互联网技术走向繁荣的基石。
在网络编程中最重要的模型便是OSI七层网络模型和TCP/IP四层网络模型。
- OSI的上面四层 (应用层、表示层、会话层、传输层)为高层,为应用程序服务;
- OSI的下面三层(网络层、数据链路层、物理层)为低层,由操作系统支持。
给大家横向对比下TCP/IP4层模型、5层模型和OSI七层模型的差别!
Ajax:简单&复杂请求?
简单请求满足一下三个条件的请求?
- 请求方法是以下三种方法之一:HEAD、GET、POST。
- HTTP的头信息不超出以下几种字段:
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type:只限于三个请求格式的类型
- text/plain
- multipart/form-data
- application/x-www-form-urlencoded
复杂请求:非简单请求就是复杂请求。
- 复杂请求在正式请求前都会有请求预检,在浏览器
NetWork
中可以看到有OPTIONS
请求;用于向服务器询问 这次请求是否在服务器允许来源之内;- 以及的方法是否符合我服务器设计的方法,从而做下一步的处理,
- 主要用于向服务器请求权限信息的。
简单请求和复杂请求的区别?
- 复杂请求会多发一次请求
- 例:我们向 3000 服务器发送 "/getdata"的get 请求,浏览器会额外发送一个"/getdata"的options请求,这个请求我们称为预请求,服务器也会做出“预响应”,预请求实际上是一种权限请求,只有预请求成功后,实际的请求才会执行,预请求也存在跨域问题哦。
预检验请求
- 对于 跨域 的复杂请求会进行预检请求;
- 预检请求是不会携带请求体和自定义的请求头; 因此对于处理复杂请求的在自定义中间件,遇到预检请求,我们需要直接放行,否则会出现非预期的结果。如果不跨域,是没有预检请求的。
复杂请求详解?
- 非简单请求就是复杂请求。 复杂请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为“预检”请求(preflight)。预检请求为OPTIONS请求,用于向服务器请求权限信息。预检请求被成功响应后,才会发出真实请求,携带真实数据。axios默认请求就是application/json。
- ajax 请求遵循同源策略(协议、域名、端口必须一致),若突破该限制,会产生跨域行为,设置Access-Control-Allow-Origin: *,可允许客户端跨域访问。 除上述情况外,还有一种请求叫做Preflighted Request(带预检的跨域请求)。
- Preflighted Request在发送真正的请求前,会先发送一个方法为OPTIONS的预请求(Preflighted Request),用于试探服务端是否能接受真正的请求。如果options获得的回应时拒绝性质的,如404、403、500等状态,就会停止post、get请求的发出。
- 请求变成Preflighted Request的情况如下:
- 请求方法不是GET/HEAD/POST
- POST请求的Content-Type并非application/x-www-form-urlencoded, multipart/form-data, 或text/plain
- 请求设置了自定义的header字段
- 例如:如果POST请求要传输的数据为 XML文档, Content-Type为application/xml或text/xml, 则发送这个请求前会发送一个预请求,或者自定义的header字段也是一样的道理。
- 所以说, 在项目中ajax对后台API的调用, OPTIONS请求是没办法去掉的, 除非后台接口不再需要在请求header中设置openId 但是由于该项目中用户信息是采用的JWT的方式,所以只好作罢。
- 但是由于该项目在后台中自定义了请求频率限制的拦截器,例如限制同一个客户端一秒内对某一个接口只能访问1次。如果超过限制,则第二次会返回状态码500,不予处理。如果每次请求前都带着一次OPTIONS请求,则该拦截器无法正常实现功能,反正会导致大批接口调用失败的情况。
- 鉴于上述分析,既然前端发起请求时OPTIONS请求没有办法去除,那么是否可以考虑从后台拦截器进行改造。
- 如果拦截到的请求不是项目中常规的GET或者POST请求,则该拦截器直接放行。