作为前端工程师,你还不懂怎么用Node写静态文件服务器吗?

使用Nodejs搭建本地静态服务器 在日常开发中,我们经常会在本地文件夹中直接打开HTML页面,一般都是file协议但当代码中存在http或https等外部资源时,HTML页面就无法正常打开,为了解决这个问题就需要搭建本地静态服务器。如果你知道怎么搭建本地静态服务器,自己用任何方式搭建都可以。如果不了解的话,建议使用nodejs去快速搭建一个本地静态服务器,因为它比较简单快捷。使用Nodejs搭建本地静态服务器,首先,查看Nodejs是否安装。在项目目录下,进入命令行窗口,输入 查看Nodejs的安装情况: 返回正确的版本号,说明这台机器已 阅读详情

背景

作为前端工程师,我想大家一定对静态文件服务器不会陌生。所谓的静态文件服务器做的工作就是将我们的前端静态文件(.js/.css/.html)传输给浏览器,然后浏览器再将我们的页面渲染出来。我们常用的webpack-dev-server就是本地开发用的静态文件服务器,而一般线上环境我们会使用nginx,因为它更加稳定和高效。既然静态文件服务器无处不在,那么它们又是如何实现的呢?本篇文章将带你手把手实现一个高效的静态文件服务器。

功能介绍

我们的静态服务器包括下面两个功能:

  • 当用户请求的内容是文件夹时,展示当前文件夹的结构信息
  • 当用户请求的内容是文件时,返回文件的内容

我们来看一下实际效果,服务端的静态文件目录是这样的:

static
└── index.html 

访问localhost:8080可以获取根目录的信息:

代码实现

根据上面的需求描述,我们先用流程图来设计一下我们的逻辑如何实现:

基础代码实现

看完上面的流程图,我相信大家的思路基本清晰了,接着我们看一下具体的代码实现:

const http = require('http')
const url = require('url')
const fs = require('fs')
const path = require('path')
const process = require('process')

// 获取服务端的工作目录,也就是代码运行的目录
const ROOT_DIR = process.cwd()

const server = http.createServer(async (req, resp) => {const parsedUrl = url.parse(req.url)// 删除开头的'/'来获取资源的相对路径,e.g: `/static`变为`static`const parsedPathname = parsedUrl.pathname.slice(1)// 获取资源在服务端的绝对路径const pathname = path.resolve(ROOT_DIR, parsedPathname)try {// 读取资源的信息, fs.Stats对象const stat = await fs.promises.stat(pathname)if (stat.isFile()) {// 如果请求的资源是文件就交给sendFile函数处理sendFile(resp, pathname)} else {// 如果请求的资源是文件夹就交给sendDirectory函数处理sendDirectory(resp, pathname)}} catch (error) {// 访问的资源不存在if (error.code === 'ENOENT') {resp.statusCode = 404resp.end('file/directory does not exist')} else {resp.statusCode = 500resp.end('something wrong with the server')}}
})

server.listen(8080, () => {console.log('server is up and running')
}) 

在上面的代码中我使用http模块创建了一个server实例,这个实例里面定义了处理所有HTTP请求的handler函数。handler函数实现比较简单,读者根据上面的代码注释就可以看明白了,这里想要说明一下我为什么使用fs.promises.stat来获取资源的元信息(fs.Stats类,包括资源的类型和更改时间等)而不使用可以实现同一个功能的fs.stat和fs.statSync:

  • fs.promises.stat vs fs.stat: fs.promises.stat是promise-style的,可以使用async和await来实现异步的逻辑,代码很干净。而fs.stat是callback-style的,这种API写异步逻辑最后可能会变成意大利面条,后期维护困难。
  • fs.promises.stat vs fs.statSync: fs.promises.stat读取文件的信息是一个异步操作,不会阻塞主线程的执行。而fs.statSync是同步的,这也就意味着当这个API执行的时候,JS主线程会卡死,其它的资源请求是处理不了的。这里我也建议当大家需要在服务端进行文件系统的读写的时候,一定要优先使用异步API而避免使用同步式的API。

接着我们来看一下sendFile和sendDirectory这两个函数的具体实现:

const sendFile = async (resp, pathname) => {// 使用promise-style的readFile API异步读取文件的数据,然后返回给客户端const data = await fs.promises.readFile(pathname)resp.end(data)
}

const sendDirectory = async (resp, pathname) => {// 使用promise-style的readdir API异步读取文件夹的目录信息,然后返回给客户端const fileList = await fs.promises.readdir(pathname, { withFileTypes: true })// 这里保存一下子资源相对于根目录的相对路径,用于后面客户端继续访问子资源const relativePath = path.relative(ROOT_DIR, pathname)// 构造返回的html结构体let content = '<ul>'fileList.forEach(file => {content += `<li><a href=${relativePath}/${file.name}>${file.name}${file.isDirectory() ? '/' : ''}</a></li>` })content += '</ul>'// 返回当前的目录结构给客户端resp.end(`<h1>Content of ${relativePath || 'root directory'}:</h1>${content}`)
} 

sendDirectory通过fs.promises.readdir来获取其底下的目录信息,然后以列表的形式返回一个html结构给客户端。这里值得一提的是:由于客户端需要按照返回的子资源信息进一步访问子资源,所以我们需要记录子资源相对于根目录的相对路径。sendFile函数的实现相对于sendDirectory会简单一点,它只需要读取文件的内容然后返回给客户端就可以了。

上面的代码写完后,我们其实已经实现了上面说的需求了,可是这个服务端是生产不可用的,因为它有很多潜在的问题没有解决,接着就让我们看一下如何解决这些问题来优化我们的服务端代码。

大文件优化

我们先来看看在现在的实现下,客户端请求一个大文件会发生什么。首先我们在static文件夹下准备一个大文件test.txt,这个文件里面有1000万行Hello World<img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fb8cdc5e242f4499a5570ef848b0f162~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.image?) 然后我们启动服务器,查看服务器启动完成后Node的内存占用情况: ![Node内存使用状况](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/32b55ae3d78d4faaa74cb2d56b17761b~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.image?) 可以看到Node服务只占用了8.5M的内存,我们在浏览器访问一下test.txt: ![浏览器访问test.tx](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0493337d81764733a55fa16f4c9016e6~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.image?) 浏览器在疯狂输出Hello World!,这个时候再看一眼Node的内存占用情况: ![内存激增](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1da0992df26c4e67af1e2c45694a3dc8~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.image?) 内存使用一下子由8.5M激增到了132.9M,而增加的资源差不多就是文件的大小124M,这到底是为什么呢?我们再来看一下sendFile`文件的实现" style=“margin: auto” />

const sendFile = async (resp, pathname) => {// readFile会读取文件的数据然后存在data变量里面const data = await fs.promises.readFile(pathname)resp.end(data)
} 

上面的代码中,其实我们会一次性读取文件的内容然后保存在data变量里面,也就是说我们会将124M的文本信息保存在内存里面!你试想一下,如果有多个用户同时访问大资源,我们的程序肯定会因为内存爆炸而OOM(Out of Memory)的。那么这个问题如何解决呢?其实node提供的stream模块可以很好地解决我们的问题。

Stream

我们先来看一下stream的官方介绍:

A stream is an abstract interface for working with streaming data in Node.js. There are many stream objects provided by Node.js. For instance, a request to an HTTP server and process.stdoutare both stream instances.Streams can be readable, writable, or both. All streams are instances of EventEmitter

简单来说,stream就是给我们流式处理数据用的,那么什么是流式处理呢?用最简单的话来说就是:不是一下子处理完数据而是一点一点地处理它们。使用stream, 我们要处理的数据就会一点一点地加载到内存的某一个固定大小的区域(buffer)以给其它消费者消费。由于保存数据的buffer大小一般是固定的,当旧的数据处理完才会加载新的数据,因此它可以避免内存的崩溃。话不多说,我们马上使用stream来重构一下上面的sendFile函数:

const sendFile = async (resp, pathname) => {// 为需要读取的文件创建一个可读流readableStreamconst fileStream = fs.createReadStream(pathname)fileStream.pipe(resp)
} 

上面的代码中,我们为需要读取的文件创建了一个可读流(ReadableStream),然后将这个流和resp对象连接(pipe)在一起,这样文件的数据就会源源不断发送给客户端了。看到这里你可能会问,为什么resp对象可以和fileStream连接在一起呢?原因就是这个resp对象底层是一个可写流(WritableStream),而可读流的pipe函数接收的就是可写流。优化完后我们再来请求一下test.txt大文件,同样浏览器一顿疯狂输出,不过这个时候Node服务的内存用量是这样的:

减少文件传输带宽

使用stream的确可以减少服务端的内存占用问题,可是它没有减少服务端和客户端传输的数据大小。换句话来说,假如我们的文件大小是2M我们就实打实传输这2M的数据给客户端。如果客户端是手机或者其它移动设备的话,这么大的带宽消耗肯定是不可取的。这个时候我们需要对被传输的数据进行压缩然后再在客户端进行解压,这样传输的数据量才能大幅度减少。服务端数据压缩的算法有很多,这里我使用了一个比较常用的gzip算法,我们来看一下如何更改sendFile以支持数据压缩:

// 引入zlib包
const zlib = require('zlib')

const sendFile = async (resp, pathname) => {// 通过header告诉客户端:服务端使用的是gzip压缩算法resp.setHeader('Content-Encoding', 'gzip')// 创建一个可读流const fileStream = fs.createReadStream(pathname)// 文件流首先通过zip处理再发送给resp对象fileStream.pipe(zlib.createGzip()).pipe(resp)
} 

在上面的代码中,我使用Node原生的zlib模块创建了一个转换流(Transform Stream),这种流是既可读又可写的(Readable and Writable Stream),所以它像是一个转换器将输入的数据进行加工然后输出到下游的可写流。我们请求index.html文件来看一下优化后的效果:

使用浏览器缓存

数据压缩虽然解决了服务端客户端传输数据的带宽问题,可是没有解决重复数据传输的问题。我们知道一般来说服务器的静态文件是很少会改变的,在服务端资源没有发生改变的前提下,同一个客户端多次访问同一个资源,服务端会传输一样的数据,而这种情况下更有效的方式是:服务器告诉客户端资源没有变化,你直接使用缓存就可以了。浏览器缓存的方式有很多种,有协商缓存和强缓存。关于这两种缓存的区别我想网络上已经有很多文章说得很清晰了,我在这里也不再多说,本篇文章主要想说一下强缓存的Etag机制如何实现。

什么是Etag

其实Etag(Entity-Tag)可以理解为文件内容的指纹,如果文件内容发生了改变那么这个指纹是大概率是会变的。这里注意的是我用了大概率而不是绝对,这是因为HTTP1.1协议里面并没有规定etag具体生成算法是什么,这完全是由开发者自己决定的。通常对于文件来说,etag是由文件的长度 + 更改时间生成的,这种做法其实是会存在浏览器读取不到最新文件内容的情况的,不过这不是本文的重点,有兴趣的同学可以参考网上的其它资料。

接着让我们图解一下基于etag的协商缓存过程:

  • 浏览器第一次请求服务端的资源时,服务端会在Response里面设置当前资源的etag信息,例如Etag: 5d-1834e3b6ea2
  • 浏览器第二次请求服务端资源时,会在请求头部的If-None-Match字段带上最新的etag信息5d-1834e3b6ea2。服务端收到请求解析出If-None-Match字段并将其和最新的服务端etag进行对比,如果是一样的就会返回304给浏览器表示资源无更新,如果资源发生了更改则将最新的etag设置到头部并且将最新的资源返回给浏览器。

接着我们来看一下sendFile函数如何支持etag:

// 这个函数会根据文件的fs.Stats信息计算出etag
const calculateEtag = (stat) => {// 文件的大小const fileLength = stat.size// 文件的最后更改时间const fileLastModifiedTime = stat.mtime.getTime()// 数字都用16进制表示return `${fileLength.toString(16)}-${fileLastModifiedTime.toString(16)}`
}

const sendFile = async (req, resp, stat, pathname) => {// 文件的最新etagconst latestEtag = calculateEtag(stat)// 客户端的etagconst clientEtag = req.headers['if-none-match']// 客户端可以使用缓存if (latestEtag == clientEtag) {resp.statusCode = 304resp.end()return}resp.statusCode = 200resp.setHeader('etag', latestEtag)resp.setHeader('Content-Encoding', 'gzip')const fileStream = fs.createReadStream(pathname)fileStream.pipe(zlib.createGzip()).pipe(resp)
 } 

在上面的代码中我新增了一个计算etag的函数calculateEtag,这个函数会根据文件的大小和最后更改时间算出文件最新的etag信息。接着我还修改了sendFile的函数签名,接收了req(HTTP请求体)和stat(文件的信息,fs.Stats类)两个新参数。sendFile会先判断客户端的etag和服务端的etag是不是一样的,如果相同就返回304给客户端否则返回文件的最新内容并且在header设置最新的etag信息。同样我们再次访问index.html文件来验证优化效果:

值得一提的是,这里我们只通过etag实现了浏览器的缓存,这是不完备的,实际的静态服务器可能会加上基于Expires/Cache-Control的强缓存和基于Last-Modified/Last-Modified-Since的协商缓存来优化。

总结

本篇文章我先实现了一个最简单能用的静态文件服务器,然后通过解决三个实际使用时会遇到的问题优化了我们的代码,最后完成了一个简单高效的静态文件服务器。

如上文所说,由于篇幅的限制,我们的实现上还是漏了很多东西的,例如MIME类型的设置,支持更多的压缩算法如deflate以及支持更多的缓存方式如Last-Modified/Last-Modified-Since等。这些内容其实在掌握了上面的方法后很容易就可以实现了,所以就留给大家在需要真正用到的时候自己实现了。

个人技术动态

创作不易,如果你从这篇文章中学到东西,请给我点一下赞或者关注,你的支持是我继续创作的最大动力!

同时欢迎关注公众号进击的大葱一起学习成长

等。这些内容其实在掌握了上面的方法后很容易就可以实现了,所以就留给大家在需要真正用到的时候自己实现了。

最后

为大家准备了一个前端资料包。包含54本,2.57G的前端相关电子书,《前端面试宝典(附答案和解析)》,难点、重点知识视频教程(全套)。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

webRTC(二):Nodejs搭建服务器 一个好的心态和一个坚持的心很重要,很多冲着高薪的人想学习前端,但是能学到最后的没有几个,遇到困难就放弃了,这种人到处都是,就是因为有的东西难,所以他的回报才很大,我们评判一个前端开发者是什么水平,就是他解决问题的能力有多强。分享一些简单的前端面试题以及学习路线给大家,狂戳这里即可获取!!!学习前端,但是能学到最后的没有几个,遇到困难就放弃了,这种人到处都是,就是因为有的东西难,所以他的回报才很大,我们评判一个前端开发者是什么水平,就是他解决问题的能力有多强。分享一些简单的前端面试题以及学习路线给大家, 阅读详情

相关推荐

给前端工程师的HTTP协议实验课:用C语言实现一个能托管网页的mini服务器

本文为前端工程师提供了一堂实践性的HTTP协议实验课,指导如何用C语言从零实现一个能托管静态网页的mini服务器。通过亲手构建Socket通信、解析HTTP请求、组装响应报文等核心流程,并结合Chrome开发者工具进行字节级对照,旨在帮助开发者深入理解HTTP协议底层原理与网络编程基础。

weixin_29223603的博客 384

nodeJS环境、搭建本地服务器运行静态文件

一:win+r 输入cmd,运行控制台,输入: cnpm install anywhere -g 二: 安装成功之后,我们来进入到一个存放静态页面的网页,运行anywhere 命令:anywhere -p 8081

King Saj 871

使用 Node.js 创建静态文件服务器

使用 Node.js 创建静态文件服务器

liuhao9999的博客 640

自己动手搭建一个简单的静态资源服务器

使用 NodeJs 快速搭建一个属于自己的静态资源服务器,使用这个小栗子来理解NodeJs 是如何运行的,为Node的学习打下一个小小的基础。

AI_dkx的博客 1986

前端领域借助 Node.js 实现前端代码的自动化部署

随着前端项目复杂度提升,手动部署面临效率低下、错误频发、环境不一致等问题。本文聚焦Node.js技术栈,系统讲解如何通过构建工具、脚本编程、CI/CD集成实现端到端的自动化部署,覆盖从代码提交到生产环境发布的全流程。案例基于主流前端框架(React/Vue),适配静态资源部署、单页应用(SPA)、微前端架构等场景。核心概念:解析Node.js在自动化部署中的核心能力,构建工具与部署流程的关系技术实现:分模块讲解构建、打包、传输、部署的具体实现方案实战案例:完整演示从本地开发到服务器上线的全链路脚本编写。

AI架构全栈开发实战笔记 1335

掌握 Node.js,提升前端开发的竞争力

本文旨在帮助前端开发者理解Node.js的价值,掌握其核心概念和应用场景,从而提升职业竞争力。内容涵盖Node.js基础、与前端开发的结合方式、实际应用案例及学习资源。核心概念与联系:解释Node.js的本质及其与前端开发的关系核心原理与架构:分析Node.js的工作原理和关键技术实际应用场景:展示Node.js在前端工作流和全栈开发中的应用学习路径与工具:提供系统学习Node.js的资源和工具推荐未来趋势与挑战:探讨Node.js生态的发展方向Node.js。

小白菜的博客 1101

搭建静态服务器_nodejs本地服务器_测试html/js

1、nodejs官网下载安装包http://nodejs.cn/安装 一路next----ok 自动映射环境系统–无需自己配置环境变量 2、控制台—输入:在这里插入代码片 node 无错–成功 3、测试目录–新建js文件两个(D:\sanweia\threejs\anydoor)—js文件两个 3.1 http.js var PORT = 8080;// var http = require('http'); var url=require('url'); var fs=require('fs')

ydk001001的博客 1171

nginx发布前端静态文件配置

nginx发布前端静态文件配置

node.js搭建简易Web服务器

node.js搭建简易Web服务器 node.js简介 Node.js 是一个基于V8引擎的JavaScript 运行环境。 V8 是为Google Chrome 提供支持的 JavaScript 引擎。 当使用 Chrome 进行浏览时,它负责处理并执行 JavaScript。 传统意义上javaScript只能在浏览器运行,因为浏览器内核主要由两部分组成:渲染引擎和javaScript引擎,前者负责HTML+CSS的渲染,后者则负责处理并执行javaScript代码。 简单来说,node.js为广大前

Geek_ting的博客 2674

单片机课程设计——交通灯

单片机课程设计——交通灯一、课程设计主要内容1.1 题目1.2摘要1.3关键词二、设计要求三、设计方案四、参考电路设计4.1.1数码管的设计4.1.2对应程序4.2.1独立按键的设计4.2.2对应程序4.2.3 使用逻辑4.3.1LED模块的设置4.3.2 LED实物图4.3.3 LED显示程序五、调试要点5.1 单片机最小系统5.2 数码管模块5.3 LED模块5.4 独立按键六、总结七、成品图完整程序 一、课程设计主要内容 1.1 题目 交通灯设计 1.2摘要 近年来,随着我国国民经济的快速发展,我国机

PKPROTEUS的博客 3万+

微信小程序返回按钮的隐藏玩法:用onShow实现数据自动刷新(附完整代码)

本文深入探讨了微信小程序中用户点击返回按钮后,如何利用onShow生命周期函数实现页面数据的自动刷新。文章对比了onLoad与onShow的差异,提供了从基础的本地存储标记到进阶的EventChannel事件通信,再到状态管理库的多种解决方案,并附有完整的代码示例,帮助开发者构建流畅的用户体验。

agile9scrum的博客 925

Serverless 风暴来袭,前端工程师如何应对?

阿里妹导读:尽管大部分前端的工作并不涉及server,但最近半年serverless这个词汇以及其引发的热烈的讨论,深深触动了阿里巴巴高级前端技术专家伐薪。作为接触前端十...

阿里技术 663

grafana对接zabbix数据展示

【配置】点击【模板】点击【创建模板】添加三个监控项:【名称】搜索【】创建的模板;点击上方【监控项】,点击创建【监控项】点击上方【触发器】点击【创建触发器】主机关联监控模板:左侧【配置】点击 【主机】点击【Zabbix server】查看:左侧点击【监测】点击【主机】点击【Zabbix server】点击最新数据,找到添加的三个模板主机关联监控模板:左侧【配置】点击 【主机】点击【Zabbix server】把监控模板用起来① 明确获取指标数据的方法。

2401_83883919的博客 6594

终极http-server配置教程:5分钟快速搭建静态文件服务器

在当今Web开发领域,快速搭建本地开发环境是每个开发者必备的技能。**http-server**作为一款简单、零配置的命令行HTTP服务器,已经成为前端开发者和全栈工程师的首选工具。这款Node.js静态文件服务器不仅安装简单、使用方便,还支持多种高级功能,能够满足从本地开发到生产环境的各类需求。本文将为你提供完整的http-server配置指南,帮助你在5分钟内快速搭建高效的静态文件服务器。

gitblog_00999的博客 958

软考 系统架构设计师历年真题集萃(248)

软考 系统架构设计师历年真题集萃(248)

phmatthaus的专栏 791

Android功耗系列专题理论之十一:高通QCOM平台待机功耗问题分析方法

本文详细介绍了高通QCOM平台待机功耗问题的分析方法。首先强调测试环境标准化的重要性,包括关闭无线功能、日志记录和非必要传感器。重点分析了硬件连接检查、驱动配置验证、电源管理策略优化等关键步骤。文章详细讲解了射频校准、时钟源/中断分析、子系统状态检查等专业技术方法,并提供了具体的命令行操作示例。此外还介绍了外设拆解、外灌电压测试等硬件排查手段,以及功耗分解板、波形分析等高级诊断技术。最后强调了固件版本验证和环境因素测试的必要性,为工程师提供了系统性的功耗问题排查思路。

771

Vercel Serve:现代化的静态文件服务工具

Vercel Serve:现代化的静态文件服务工具 【免费下载链接】serve Static file serving and directory listing 项目地址: https://gitcode.com/gh_mirr...

gitblog_00885的博客 449

SAN存储与协议,了解SCSI、FC和ISCSI

在前面我们介绍SAN存储及iSCSI协议的时候了解到SAN存储其实是一个CS架构的系统。存储系统本身就是整个系统的服务端。以IP-SAN(也就是基于iSCSI的SAN存储)为例,其整体架构如图1所示。 图1 CS架构 对于存储系统来说,通常是由专业的存储厂商提供,比较知名的如EMC、NetAPP、IBM和日立等等。国内存储厂商也迅速崛起,比较知名的如华为、宏杉、浪潮和同友等等。另外,还有一些小的存储厂商,他们往往集中在某个领域,比如专注文件系统或者块存储等等。 除了专业的存储设备外,其实Linux

shuningzhang的专栏 2685

Windows 10/11 快速升级与装机指南:MediaCreationTool.bat 一份脚本搞定 ISO、U 盘与 TPM 绕过

下午两点,你面前摆着三台待交付的旧机器:一台还停在 Windows 7 Ultimate,一台是 8.1 Home,另一台跑着 10 Enterprise LTSB。客户的要求很直白——全部升到 Windows 11,装完能直接开机用。你手头没有任何现成的安装盘,只有网络,和一段想早点下班的心情。这时你要打开的,是 [MediaCreationTool.bat](https://link.gitc

gitblog_00472的博客 633

docker容器ubuntu:latest里使用uv add mysqlclient安装失败的解决方案

在Docker容器(ubuntu:latest)中安装mysqlclient失败,原因是缺少必要的依赖包。错误显示系统找不到pkg-config工具和MySQL客户端库。解决方法:先更新软件源并安装构建工具、Python开发包、MySQL客户端库和pkg-config工具。具体步骤:运行sudo apt update,然后安装build-essential python3-dev default-libmysqlclient-dev pkg-config,最后再执行uv add mysqlclient即可成

拥抱具身智能,昇腾Ascend C 295

CE电流法测试中的dBμV负值解析

传导发射(CE)电流法测试中出现的dBμV负值现象表明被测设备干扰电平低于1μV参考基准。这源于对数计算特性(小于1μV的电压转换后为负值)、设备优良的EMC设计(如滤波效果显著)及测试环境的影响(LISN隔离、屏蔽室低噪声)。负值虽不代表实际负电压,但反映干扰水平优于标准限值,为系统集成预留电磁裕度。工程应用中需结合设备灵敏度、环境背景噪声等因素综合分析,避免误判,这类数据可用于评估EMI设计冗余度。

硬核科技 298

从前端到前端框架

这是一篇笔记,主要用于帮助刚入门Web全栈不久的同学。以及个人思路的记录整理。如果你是一个全栈大师就可以直接跳过了。当然想加深一下理解也没有问题。可能会较多谈谈我的个人见解。概念越来越抽象了,差点没理解……仅供大家参考,方便后续忘记定义的时候查阅。是一个基于Chrome V8引擎的JavaScript运行环境,用于在服务器端运行JavaScript代码。它允许开发人员使用JavaScript构建服务器端应用程序。是一个用于构建用户界面的JavaScript框架,运行在浏览器中。

Pleasure1234的博客 2101

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

全栈工程师陆金雨

陆金雨是全栈工程师,精通前端用户界面(UI)和用户体验(UX)的设计与开发,还深入了解后端服务器逻辑、数据库管理、系统架构、API设计和网络安全等多个方面。全栈工程师能够参与项目从需求分析、设计、开发到部署和维护的全过程,有效提升项目效率,确保产品质量。:Web开发的基础,构建静态网页和动态交互的核心技术。:现代前端框架之一,用于构建高效、可维护的Web应用程序。:状态管理库,帮助管理复杂的应用程序状态。:前端构建工具,用于模块打包、优化和资源管理。TypeScript。

2403_87133824的博客 1473

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Nginx是一个非常流行的开源Web服务器和反向代理服务器,它特别适合用于提供静态文件服务

它可以根据HTTP请求的URL和其他参数进行缓存,并在下次相同请求时直接返回缓存的内容,提高响应速度和系统的吞吐量。反向代理服务器:Nginx可以作为反向代理服务器,将客户端的请求转发给后端的多个服务器,实现负载均衡和高可用性。静态资源服务:Nginx可以快速地处理静态文件的请求,如HTML、CSS、JavaScript、图片等,通过配置简单的静态文件目录即可提供高效的静态资源服务。总之,Nginx是一个功能强大、性能优越的Web服务器和反向代理服务器,特别适合用于提供静态文件服务和处理高并发连接的场景。

[Blog][Domain] programb.blog.youkuaiyun.com 1267

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Node.js 入门到干活,10 个优质项目就够了!

Node.js 在很多大公司都有不错的实践,比如:淘宝、天猫 Web 版,很多页面都是在 Node 服务器上渲染的。还有各种脚手架、前端打包发布工具、构建生态的小工具,也基本都是 Node.js 编写的。 综上,Node.js 也就成为了前端工程师挑战高薪的必备技能了! 那么 Node.js 从入门到干活,有需要学些什么呢?按照实验楼倡导的“learn by doing“,为大家奉上以下项目课程...

实验楼--动手做实验,轻松学IT! 545

Node.js一小时实战:从零构建Web服务器,打通全栈开发

如果你是一名前端开发者,或者对JavaScript非常熟悉,却一直对“后端”和“服务器”这些概念感到陌生和畏惧,那么这篇文章就是为你准备的。你可能已经熟练掌握了React、Vue,能用JavaScript在浏览器里做出各种交互,但一旦涉及到搭建一个能处理请求、连接数据库的“服务”,就感觉无从下手,仿佛要重新学习一门新的语言和一套完全不同的思维模式。 这种割裂感正是Node.js要解决的核心问题。它不是一个全新的语言,而是一个 让JavaScript脱离浏览器,在服务器端运行的环境 。这意味着,你过去积累的所

weixin_26869081的博客 358
上一篇: 组员大眼瞪小眼,forEach处理异步任务遇到的坑
下一篇: @property自定义CSS属性,实现不一样的动画效果
梅花十三儿
博客等级 码龄5年 1038粉丝 444原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值