Node.js学习记录(二)

目录

一、express

1、初识express

2、安装express

3、创建并启动web服务器

[4、监听 GET&POST 请求、响应内容给客户端](#4、监听 GET&POST 请求、响应内容给客户端)

5、获取URL中携带的查询参数

6、获取URL中动态参数

7、静态资源托管

二、工具nodemon

三、express路由

1、express中路由

2、路由的匹配

3、路由模块化

4、路由模块添加前缀

四、中间件

1、express中间件

2、express中间件调用流程

3、中间件格式

4、创建并使用中间件函数

全局生效中间件

局部生效中间件

5、中间件作用

6、中间件分类

[express.json & POST请求数据的接收](#express.json & POST请求数据的接收)

7、自定义中间件

[五、Express 编写接口](#五、Express 编写接口)

[1、编写get 、post 方式接口](#1、编写get 、post 方式接口)

[2、cors 解决跨域](#2、cors 解决跨域)

[3、关于 cors](#3、关于 cors)

[cors 响应头](#cors 响应头)

Access-Control-Allow-Origin

Access-Control-Allow-Headers

Access-Control-Allow-Methods

cors请求分类

4、JSONP

5、express中使用session

[6、express中使用 JWT生成token](#6、express中使用 JWT生成token)


Node.js学习记录(一)-CSDN博客

接着上一篇继续学习node.js

一、express

1、初识express

express类似node.js中http模块,专门用来创建WEB服务器的,相对node中http更加方便、功能更加强大;本质是npm上提供的第三方包。官网地址:Express - 基于 Node.js 平台的 web 应用开发框架 - Express中文文档 | Express中文网

express是基于node.js封装出来的,使用express可以快速创建这两种服务器。

2、安装express

javascript 复制代码
npm i express@4.17.1 //安装指定版本
npm i express //不指定版本直接安装

3、创建并启动web服务器

先新建个express练习目录 express, 里面新建express_test.js

(顺便 npm init -y 初始化一个package.json 文件,后面会用 )

javascript 复制代码
//导入express
const express = require('express')
//创建服务器
const app = express()
//启动服务器
app.listen(3000,()=>{
    console.log('服务器启动了')
})

4、监听 GET&POST 请求、响应内容给客户端

javascript 复制代码
//导入express
const express = require('express')
//创建服务器
const app = express()

//监听请求,并向客户端响应数据 (指定user页面)
app.get('/user',(req,res)=>{
  res.send('hello express')
})
app.post('/user',(req,res)=>{
  res.send({name:'张三',age:18})
})

//启动服务器
app.listen(3000,()=>{
  console.log('服务器启动了 http://127.0.0.1:3000')
})

请求中的两个参数:req 请求对象、res 响应对象

用 app.get 监听get请求,app.post 监听post请求

通过res.send() 向客户响应数据

运行结果

5、获取URL中携带的查询参数

可以通过req.query对象查询 如链接:http://127.0.0.1:3000/user?id=1&name=test&str=%E5%AD%97%E7%AC%A6

javascript 复制代码
//监听请求,并向客户端响应数据
app.get('/user',(req,res)=>{
  res.send('hello express')
  console.log('请求的参数:',req.query)
})
app.post('/user',(req,res)=>{
  res.send({name:'张三',age:18})
  console.log('请求的参数:',req.query)
})

6、获取URL中动态参数

通过req.params对象访问URL中通过**:**匹配到的动态参数

默认req.params是一个空对象, 示例链接:http://127.0.0.1:3000/user/9?id=1&name=test&str=%E5%AD%97%E7%AC%A6

javascript 复制代码
//导入express
const express = require('express')
//创建服务器
const app = express()

//监听请求,并向客户端响应数据 
//app.get('/user/:id/:name',(req,res)=>{
app.get('/user/:id',(req,res)=>{
  res.send('hello express')
  console.log('请求的动态参数参数:',req.params)
})

//启动服务器
app.listen(3000,()=>{
  console.log('服务器启动了 http://127.0.0.1:3000')
})

:<key> ,这个key起什么名字,打印里面就会得到什么,比如 :name ,打印就会得到{name:9},

:<key1>/:<key1>参数可以有多个,如 http://127.0.0.1:3000/user/9/test?id=1&name=test&str=%E5%AD%97%E7%AC%A6

7、静态资源托管

express 提供了express.static(),可以方便地创建一个静态资源服务器,如:可以通过代码将图片、css、js等文件对外开放访问

javascript 复制代码
app.use(express.static('public'))

express在指定静态目录下查找文件,并提供对外访问路径,但存放静态文件的目录名不会出现在url中。

如下面示例中托管images和other文件夹后,访问里面的文件

images文件夹中图片:http://localhost:3000/1.png

other文件夹中css文件:http://localhost:3000/reset.css

(查找顺序是按照代码中写的顺序进行查找文件)

javascript 复制代码
const express = require('express')
const app = express()
//托管images文件夹
app.use(express.static('./images'))
//如果托管多个就继续添加,如:托管other目录
app.use(express.static('./other'))

app.listen(3000, () => {
    console.log('Server is running here: http://localhost:3000')
})

挂载路径前缀

如果想要再访问的路径前有个前缀,则可以通过代码设置,访问地址http://localhost:3000/public/reset.css

javascript 复制代码
//app.use('/前缀名字自己起',express.static('要托管的资源'))
app.use('/public',express.static('./other'))

二、工具nodemon

每次修改代码都需要重启服务,nodemon工具会监听代码变化,当代码有修改保存会自动重启,不用手动重启项目

1、安装nodemon

javascript 复制代码
npm i -g nodemon 

2、执行

javascript 复制代码
//安装nodemon 之前执行方式  :node node.js
//安装后
nodemon node.js

三、express路由

1、express中路由

客户端的请求与服务器处理函数之间的映射关系

javascript 复制代码
//app.请求类型(请求url,处理函数)
//app.METHOD(PATH,HANDLER)
app.get('/', (req, res) => {
    res.send('hello word')
})

2、路由的匹配

每一个请求到达服务器,都需要先经过路由匹配,只有匹配成功才会调用对应的处理函数;

匹配时会按照路由顺序进行匹配,如果请求的类型和URL同时匹配成功,express才会将这次请求转给对应的function进行处理

3、路由模块化

为了方便对路由进行模块化管理,express不建议将路由直接挂载到app上,推荐抽离为单独的模块。

①、新建路由文件router.js

javascript 复制代码
//express/router.js
const express = require('express')
//导入路由对象
const router = express.Router()

//挂载具体路由
router.get('/user/list', (req, res) => {
  res.send('get user list')
})
router.post('/user/add', (req, res) => {
  res.send('add user')
})
//导出路由
module.exports = router

②、注册并使用路由模块

javascript 复制代码
//express/express_test.js
const express = require('express')
const useRouter = require('./router')//引入路由文件
const app = express()

//注册路由
app.use(useRouter)

app.listen(3000, () => {
    console.log('Server is running http://localhost:3000')
})

**app.use()**这个函数作用是用来注册全局中间件

4、路由模块添加前缀

和静态资源托管类似(在一大类7小条中),添加一个统一访问前缀

javascript 复制代码
//如添加统一前缀 api
// 把 ② 中代码 app.use(useRouter) 变更如下
app.use('/api',useRouter)

四、中间件

1、express中间件

2、express中间件调用流程

当一个请求到达express服务器后,可以连续调用多个中间件,从而对这次请求进行预处理

3、中间件格式

本质上是function处理函数

中间件函数的形参列表中,必须包含next参数,而路由处理函数中 只包含req、res。

next函数的作用:是实现多个中间件连续调用的关键,它表示把流转关系转交给下一个中间件或路由

当前中间件处理完了调用next() 后就会转交给下一个中间件

4、创建并使用中间件函数

全局生效中间件

客户端发起请求到达服务器之后,都会触发的中间件,叫全局生效的中间件。

使用app.use(中间件函数) ,即自定义一个全局生效的中间件

javascript 复制代码
const express = require('express')
const app = express()

//自定义一个中间件 并注册使用
// const mn = function(req,res,next){
//     console.log('定义一个中间件')
//     next()
// }
// //注册使用中间件
// app.use(mn)

//或者直接简化
app.use(function(req,res,next){
    console.log('定义一个中间件')
    next()
})

app.listen(3000, () => {
    console.log('Server is running http://localhost:3000')
})

如果定义多个全局中间件,会按照中间件定义先后顺序依次进行调用。

局部生效中间件

不使用app.use()定义的中间件叫局部中间件;只对某个路由生效的中间件,不会影响其他路由。

局部中间件可以写多个或单个,多个用逗号隔开(多个也可以是数组形式)。

app.get('/',mn1, mn2,mn3,(req, res) => { res.send('Hello World') })

app.get('/',[mn1, mn2,mn3],(req, res) => { res.send('Hello World') })

javascript 复制代码
//express\express_test.js
const express = require('express')
const app = express()
//定义一个局部中间件
const mn = function(req, res, next) {
    console.log('这是局部中间件')
    next()
}

//局部生效的中间件
//app.get(URL,局部中间件参数, (req, res) => {

//定义一个get路由
app.get('/',mn, (req, res) => {
    res.send('Hello World1')
})
app.post('/',(req, res) => {
    res.send('Hello World2')
})

app.listen(3000, () => {
    console.log('Server is running http://localhost:3000')
})

当访问get路由时会执行打印,访问post路由时不会执行。

5、中间件作用

多个中间件之间共享一个 req 和 res, 这样可以在上游的中间件中统一为 req和res 添加自定义属性或方法,供下游中间件或路由使用

如:在中间件中获取当前时间,把获取的时间挂到req的startTime属性上,在路由中也可以获取到这个时间。

中间件注意事项:

1、必须在路由之前注册中间件

2、执行完中间件代码后,一定不要忘记调用 next() 函数

3、防止代码混乱,调佣next()函数后不要在写额外代码

4、错误级别中间件必须注册在所有路由之后

6、中间件分类

express.json & POST请求数据的接收

如果是post请求,可以使用req.body这个属性,来接收客户端发送过来的请求体数据。

默认情况下,如果不配置解析表单数据的中间件,则 req.body 默认等于 undefined。

如果不使用express.json()、express.urlencoded()可以使用三方的一个中间件:body-parser 来解析请求体数据

注:express内置的中间件express.urlencoded 就是基于 body-parser 这个三方中间件进一步封装出来的

javascript 复制代码
const express = require('express')
const app = express()

//解析json格式的请求数据
app.use(express.json())

//解析表单数据和 url-encoded 格式的请求数据
app.use(express.urlencoded())

app.post('/',(req, res) => {
    console.log(req.body)
    res.send({"name":"John"})
})

app.listen(3000, () => {
    console.log('Server is running http://localhost:3000')
})

javascript 复制代码
//1.导入解析表单数据的中间件 body-parserconst 
const parser = require('body-parser')

//2.使用 app.use()注册中间件
app.use(parser.urlencoded({extended: false})

7、自定义中间件

javascript 复制代码
const express = require('express');
const app = express()
const qs = require('querystring')//node内置模块 解析和格式化网址查询字符串
app.use((req,res,next)=>{
    let str = ''
    req.on('data',(chunk)=>{
        console.log('data事件====',chunk)
        str += chunk
    })
    req.on('end',()=>{
        console.log('end事件====',str)
        console.log(qs.parse(str)) //解析出传递数据

        next()//调用next()函数
//注意要放在req.on('end', ...) 内部的回调函数中,需要在数据完全接收并解析后再继续处理请求
    })

})
app.post('/user',(req,res)=>{
    res.send(req.body)//响应给客户端接收到的数据
})
app.listen(3000,()=>{
    console.log('server is running http://localhost:3000')
})

使用postman发起post请求并传递4个参数,运行结果如下,返回结果可以使用node内置模块querystring进行把字符串解析成json

如果要实现自定义中间件模块化,实现步骤类似express路由模块化类似,这里就不写具体步骤了~

五、Express 编写接口

准备工作 :新建apiRouter.js

目录结构

G:\myproject\express

express

|---- express_test.js //运行主页

|---- apiRouter.js // 路由模块文件

1、编写get 、post 方式接口

①、创建一个基本服务

②、创建API路由模块apiRouter.js并导出

③、编写 GET & POST 接口逻辑

④、导入路由模块

javascript 复制代码
//apiRouter.js
//导入express、router
const express = require('express')
const router = express.Router()

//定义get方式请求  接口名为bookname
router.get('/bookname',(req,res)=>{
  //通过req.query获取get请求参数
  const query = req.query

  //向客户端响应处理结果
  res.send({
    status:200,//200表示成功 204表示失败
    msg:'GET请求成功',
    data:query,//返回给客户端的数据, 这里示例直接把客户端传过来的数据返回给用户
  })
})

//定义post方式请求 接口名为 shopname
router.post('/shopname',(req,res)=>{
  //通过req.body获取post请求参数
  const body = req.body

  //向客户端响应处理结果
  res.send({
    status:200,//200表示成功 204表示失败
    msg:'POST请求成功',
    data:body,//返回给客户端的数据
  })
})

//导出路由
module.exports = router
javascript 复制代码
// express_test.js 
//express 编写接口
const express = require('express')
const app = express()


//========此端 是jsonp 接口例子 ============ 配置jsonp 接口  必须在cors之前调用 (jsonp 是get的)=====================
app.get('/api/jsonp',(req,res)=>{
    //接收客户端发送的回调函数名称
    const funcName = req.query.callback
    //要发送给客户端的数据
    const data = {name:'测试jsonp',age:18}
    //拼接一个完整的字符串
    const result = `${funcName}(${JSON.stringify(data)})`
    //将拼接好的字符串返回给客户端
    res.send(result)
})
//==================== 配置jsonp 接口  end =====================


//=========== 此两行是解决跨域问题的 =================
const cors = require('cors')

//配置解决跨域问题  注意:必须在注册路由之前调用
app.use(cors())
//============此两行是解决跨域问题的  end =============

//配置解析表单数据的中间件  记得放在注册路由之前 (post 时会用)
app.use(express.urlencoded({extended:false}))

//导入路由模块
const useRouter = require('./apiRouter')

//注册路由,并设置统一前缀,名为api
app.use('/api',useRouter)

app.listen(3000,()=>{
    console.log('服务器启动成功 http://127.0.0.1:3000')
})

启动服务(node express_test.js , 或者如果安装了nodemon工具 nodemon express_test.js),通过浏览器或者postman访问 http://127.0.0.1:3000/api/bookname?id=12&name=%E8%A5%BF%E6%B8%B8%E8%AE%B0&english=xiyouji&price=888

2、cors 解决跨域

和js同级新建一个index.html,接口用刚刚写好的试验会发现有跨域问题

解决接口跨域主要有两种:

1、CORS (主流的解决方案)

2、JSONP (有缺陷的解决方案:只支持 GET 请求)
cors 是 Express 的一个三方中间件,安装配置cors可解决跨域问题

①、npm i cors 安装中间件

②、const cors = require('cors') 导入中间件

③、在路由前导入配置中间件 app.use(cors())

此时在运行html,点击按钮请求接口就可以成功返回数据

3、关于 cors

CORS (Cross-Origin Resource Sharing,跨域资源共享)由一系列 HTTP 响应头组成,这些 HTTP 响应头决定浏览器是否阻止前端 JS 代码跨域获取资源。

浏览器的同源安全策略默认会阻止网页"跨域"获取资源。但如果接口服务器配置了 CORS 相关的 HTTP 响应头就可以解除浏览器端的跨域访问限制。

注意:

①、CORS 主要在服务器端进行配置 。客户端浏览器无须做任何额外的配置,即可请求开启了 CORS 的接口。

②、CORS 在浏览器中有兼容性。只有支持 XMLHttpRequest Level2 的浏览器,才能正常访问开启了 CORS 的服务端接口(例如:IE10+、Chrome4+、FireFox3.5+)。

cors 响应头

Access-Control-Allow -Origin
javascript 复制代码
//格式
//<origin> 参数的值指定了 允许访问该资源的外域URL                          
Access-Control-Allow-Origin:<origin> | *
javascript 复制代码
//通配符 *,允许所有的域名访问
res.setHeader('Access-Control-Allow-0rigin','*')

//只允许 来自 https://test.com 域名下的访问
res.setHeader('Access-Control-Allow-0rigin','https://test.com')
Access-Control-Allow -Headers

默认情况下cors仅支持 客户端向服务器发送如下9个请求头:

Accept、Accept-Language、Content-Language、DPR、Downlink、Save-Data、Viewport-Width、 Width、Content-Type ( 值仅限于 text/plain、multipart/form-data、application/x-www-form-urlencoded 三者之一)

如果客户端向服务器发送了额外的请求头信息,则需要在服务器端,通过 Access-Control-Allow-Headers 对额外的请求头进行声明,否则这次请求会失败!

javascript 复制代码
//允许客户端额外向服务器发送Content-Type 请求头和 X-Custom-Header 请求头
//注意:多个请求头之间使用英文的逗号进行分割
//如额外声明了 Content-Type 和 Custom-Header 两个请求头
res.setHeader('Access-Control-Allow-Headers','Content-Type,Custom-Header')
Access-Control-Allow -Methods

默认情况下,CORS 仅支持客户端发起 GET、POST、HEAD 请求。

如果客户端希望通过 PUT、DELETE等方式请求服务器的资源,则需要在服务器端,通过 Access-Control-Alow-Methods来指明实际请求所允许使用的 HTTP 方法。

javascript 复制代码
//只允许 POST, GET, DELETE, HEAD 请求方法
res.setHeader('Access-Control-Allow-Methods','POST, GET, DELETE, HEAD')

//允许所有请求方法
res.setHeader('Access-Control-Allow-Methods','*')

cors请求分类

根据请求方式和请求头的不同可以分为2大类:简单请求 和 预检请求

简单请求(同时满足以下2点):

①、请求方式是GET、POST、HEAD三者之一

②、HTTP 头部信息不超过以下几种字段:无自定义头部字段、Accept、Accept-Language、Content-Language、DPR、Downlink、Save-Data、Viewport-Width、Width 、Content-Type(只有三个值application/x-www-form-urlencoded、multipart/form-data、text/plain)

预检请求(符合以其中1点):

①、请求方式为GET、POST、HEAD之外的请求 Method类型

②、请求头中包含自定义头部字段

③、向服务器发送了 application/json 格式的数据

预检请求:在浏览器与服务器正式通信之前,浏览器会先发送 OPTION 请求进行预检,以获知服务器是否允许该实际请求,所以这-次的 OPTION 请求称为"预检请求"。服务器成功响应预检请求后,才会发送真正的请求,并且携带真实数据。
二者区别:

简单请求的特点:客户端与服务器之间只会发生一次请求。

预检请求的特点:客户端与服务器之间会发生两次请求,OPTION 预检请求成功之后,才会发起真正的请求。

预检请求示例

javascript 复制代码
//在上面apiRouter.js 中添加如下代码
//定义delete方式请求
router.delete('/delete',(req,res)=>{
  //通过req.query获取get请求参数
  const query = req.query

  //向客户端响应处理结果
  res.send({
    status:200,//200表示成功 204表示失败
    msg:'DELETE请求成功',
    data:query,//返回给客户端的数据
  })
})
javascript 复制代码
//html 中添加如下测试代码
<div class="post" onclick="delet()">请求delet接口测试</div>

function delet(){
  $.ajax({
    type:"delete",
    url:"http://127.0.0.1:3000/api/delete?id=12",
    success:function(data){
      console.log('delete接口请求返回',data);
    }
  })
}

启动服务,分别点击按钮,查看控制台中的网络,点击get或者post按钮都只有1次,但是delete 会有2次

4、JSONP

浏览器端通过 <script>标签的 src 属性,请求服务器上的数据,同时,服务器返回一个函数的调用。这种请求数据的方式叫做 JSONP。

JSONP特点:

① JSONP 不属于真正的 Ajax 请求,因为它没有使用 XMLHttpRequest 这个对象

② JSONP 仅支持 GET 请求,不支持 POST、PUT、DELETE 等请求

注意:如果项目中已经配置了 CORS 跨域资源共享,为了防止冲突,必须在配置 CORS 中间件之前声明 JSONP 的接口。否则JSONP 接口会被处理成开启了CORS的接口。

javascript 复制代码
 //优先创建 JSONP 接口
 app.get('/api/jsonp',(req,res)=>{ }) //这个接口不会被处理成 CORS 接口

// 再配置CORS中间件
//这个后面的所有接口,都会被处理成 CORS 接口
app.use(cors())

app.get('/api/get',(req,res)=>{})//比如这个就是开启了CORS 的接口
javascript 复制代码
//express_test.js
//jsonp接口 
//具体代码在 五 中第1小节代码中有标注
javascript 复制代码
//html 中继续添加
<div class="post" onclick="jsonp()">请求jsonp接口测试</div>

function jsonp(){
  $.ajax({
    type:"get",
    url:"http://127.0.0.1:3000/api/jsonp",
    dataType:"jsonp",
    success:function(data){
      console.log('jsonp接口请求返回',data);
    }
  })
}

5、express中使用session

Cookie 是存储在用户浏览器中的一段不超过4KB 的字符串。它由一个名称(Name)、一个值(Value)和其它几个用于控制 Cookie 有效期、安全性、使用范围的可选属性组成。

不同域名下的 Cookie 各自独立,每当客户端发起请求时,会自动把当前域名下所有未过期的 Cookie 一同发送到服务器

Cookie特性:自动发送、域名独立、过期时限、4KB限制、不具安全性express提供三方中间件 express-session

javascript 复制代码
npm i express-session //安装

引入并注册,具体使用字段可查询官网说明:https://www.npmjs.com/package/express-session

javascript 复制代码
//express_test.js
//继续在 express_test.js 文件中导入session并全局注册
const session = require('express-session')
app.use(session({
        secret:'keyboard cat',
        resave:false,
        saveUninitialized:true
    })
)

6、express中使用 JWT生成token

安装jsonwebtoken、express-jwt

jsonwebtoken 用于生成 JWT 字符串

express-jwt 用于将 JWT 字符串解析还原成 JSON 对象

javascript 复制代码
npm install jsonwebtoken express-jwt

我这里遇到一个问题 安装完express-jwt后下面引用时一直报错 ++expressJWT is not a function++ 默认安的8+版本,按照官网的方式修改引入也报错,后来降低版本可以

项目中导入包

javascript 复制代码
//express_test.js
const jwt = require('jsonwebtoken') //导入生成jwt字符串的包
const expressJWT = require('express-jwt')//解析由jwt生成字符串的包

const secretKey = 'test password' //定义一个秘钥,值是一个字符串

定义secret秘钥

了保证 JWT 字符串的安全性,防止 JWT 字符串在网络传输过程中被别人破解,定义一个用于加密和解密的 secret 密钥:

① 当生成 JWT 字符串的时候,需要使用 secret 密钥对用户的信息进行加密,最终得到加密好的JWT 字符串

② 当把 JWT 字符串解析还原成 JSON 对象的时候,需要使用 secret 密钥进行解密

写一个登录和用户信息接口

javascript 复制代码
//express_test.js
const express = require('express')
const app = express()
const cors = require('cors')//解决跨域
const session = require('express-session')//保存session

const jwt = require('jsonwebtoken')
const expressJWT = require('express-jwt')
const secretKey = 'test password' //定义一个秘钥,值是一个字符串


//配置解决跨域问题  注意:必须在注册路由之前调用
app.use(cors())

//配置解析表单数据的中间件  记得放在注册路由之前
app.use(express.urlencoded({extended:false}))
//unless 指定带有api的接口不需要访问权限
app.use(expressJWT({secret:secretKey}).unless({ path: [/^\/api\//] }) ) //注册解密token的中间件

//注册 session 全局中间件
app.use(session({
    secret:secretKey,
    resave:false,
    saveUninitialized:true
}) )


//登录接口
app.post('/api/login',(req,res)=>{
    if(req.body.username === 'admin' && req.body.password === '123456'){
      const userInfo = req.body
      req.session.userInfo =userInfo
      req.session.isLogin = true
     //expiresIn 设置token有效时间
      const token = jwt.sign({username:userInfo.name},secretKey,{expiresIn:'50s'}) //对用户信息进行加密
  
      res.send({
        status:200,
        msg:'登录成功',
        data:{
          token:token,
          ...req.body,
        }
      })
    }else{
      res.send({
        status:204,
        msg:'用户名或密码错误',
        data:req.body
      })
    }
  
})
//获取用户信息接口
app.post('/user',(req,res)=>{
    if(req.session.isLogin){
      res.send({
        status:200,
        msg:'获取用户信息成功',
        data:req.session.userInfo
      })
    }else{
      res.send({
        status:204,
        msg:'获取用户信息失败',
        data:req.session.userInfo
      })
    }
})

//
app.listen(3000,()=>{
    console.log('服务器启动成功: http://127.0.0.1:3000')
})

注意:获取用信息时,请求头的key是authorization 值 一定要加上Bearer空格后加上token

相关推荐
图灵苹果42 分钟前
【个人博客hexo版】hexo安装时会出现的一些问题
前端·前端框架·npm·node.js
新知图书7 小时前
Node.js运行环境搭建
node.js
南辞w8 小时前
Webpack和Vite的区别
前端·webpack·node.js
等你许久_孟然10 小时前
【webpack4系列】webpack构建速度和体积优化策略(五)
前端·webpack·node.js
营赢盈英10 小时前
Using OpenAI API from Firebase Cloud Functions in flutter app
ai·node.js·openai·googlecloud·firebase
刘懿儇14 小时前
NVM(node.js版本工具)的使用
node.js
沙漏无语17 小时前
npm 设置国内镜像源
前端·npm·node.js
学海无涯,行者无疆20 小时前
通用接口开放平台设计与实现——(31)API服务线程安全问题确认与修复
接口·netty·开放平台·接口开放平台·通用接口开放平台
架构师ZYL20 小时前
node.js+Koa框架+MySQL实现注册登录
前端·javascript·数据库·mysql·node.js
flytam20 小时前
node.js 中的进程和线程工作原理
node.js