NodeJS基础到入门EXPS⑥

news2024/11/24 12:43:47

文章目录

  • ✨文章有误请指正,如果觉得对你有用,请点三连一波,蟹蟹支持😘
  • 前言
  • Express框架
  •    Router路由
    • NEST 方法
    • 路由端点
    • 使用回调函数数组处理路由
    • 使用混合使用函数和函数数组处理路由
    • 中间件的分类及用法
    •    1、应用级中间件
    •    2、路由级中间件
    •    3、获取请求参数
    •    4、错误处理中间件
    •    5、内置中间件 静态资源
    •    6、第三方中间件
    •    7、服务端渲染(模板引擎)
    •    8、express生成器
  • Node&MongoDB
  •     第一步 连接数据库
  •     第二步 创建User Mongodb模型
  •     第三步 简单使用 Mongodb命令
  •     第四步 规范使用 Mongodb命令 (RESTful架构)
  • 总结


✨文章有误请指正,如果觉得对你有用,请点三连一波,蟹蟹支持😘

                    ⡖⠒⠒⠒⠤⢄⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸   ⠀⠀⠀⡼⠀⠀⠀⠀ ⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢶⣲⡴⣗⣲⡦⢤⡏⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⠋⠉⠉⠓⠛⠿⢷⣶⣦⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠇⠀⠀⠀⠀⠀⠀⠘⡇⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡞⠀⠀⠀⠀⠀⠀⠀⢰⠇⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⡴⠊⠉⠳⡄⠀⢀⣀⣀⡀⠀⣸⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⢸⠃⠀⠰⠆⣿⡞⠉⠀⠀⠉⠲⡏⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠈⢧⡀⣀⡴⠛⡇⠀⠈⠃⠀⠀⡗⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣱⠃⡴⠙⠢⠤⣀⠤⡾⠁⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⢀⡇⣇⡼⠁⠀⠀⠀⠀⢰⠃⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⣸⢠⣉⣀⡴⠙⠀⠀⠀⣼⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⡏⠀⠈⠁⠀⠀⠀⠀⢀⡇⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⢸⠃⠀⠀⠀⠀⠀⠀⠀⡼⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⣰⠃⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⣀⠤⠚⣶⡀⢠⠄⡰⠃⣠⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⢀⣠⠔⣋⣷⣠⡞⠀⠉⠙⠛⠋⢩⡀⠈⠳⣄⠀⠀⠀⠀⠀⠀⠀
⠀⡏⢴⠋⠁⠀⣸⠁⠀⠀⠀⠀⠀ ⠀⣹⢦⣶⡛⠳⣄⠀⠀⠀⠀⠀
⠀⠙⣌⠳⣄⠀⡇   不能   ⡏⠀⠀  ⠈⠳⡌⣦⠀⠀⠀⠀
⠀⠀⠈⢳⣈⣻⡇   白嫖 ⢰⣇⣀⡠⠴⢊⡡⠋⠀⠀⠀⠀
⠀⠀⠀⠀⠳⢿⡇⠀⠀⠀⠀⠀⠀⢸⣻⣶⡶⠊⠁⠀⠀
⠀⠀⠀⠀⠀⢠⠟⠙⠓⠒⠒⠒⠒⢾⡛⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⣠⠏⠀⣸⠏⠉⠉⠳⣄⠀⠙⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⡰⠃⠀⡴⠃⠀⠀⠀⠀⠈⢦⡀⠈⠳⡄⠀⠀⠀⠀⠀⠀⠀
⠀⠀⣸⠳⣤⠎⠀⠀⠀⠀⠀⠀⠀⠀⠙⢄⡤⢯⡀⠀⠀⠀⠀⠀⠀
⠀⠐⡇⠸⡅⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⡆⢳⠀⠀⠀⠀⠀⠀
⠀⠀⠹⡄⠹⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣇⠸⡆⠀⠀⠀⠀⠀
⠀⠀⠀⠹⡄⢳⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⡀⣧⠀⠀⠀⠀⠀
⠀⠀⠀⠀⢹⡤⠳⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣷⠚⣆⠀⠀⠀⠀
⠀⠀⠀⡠⠊⠉⠉⢹⡀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡎⠉⠀⠙⢦⡀⠀
⠀⠀⠾⠤⠤⠶⠒⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠙⠒⠲⠤⠽   

前言

  1. Node.js是一个javascript运行环境。它让javascript可以开发后端程序,实现几乎其他后端语言实现的所有功能,可以与```PHP、Java、Python、.NET、Ruby等后端语言平起平坐。
  2. Nodejs是基于V8引擎,V8是Google发布的开源JavaScript引擎,本身就是用于Chrome浏览器的JS解释,但是Node之父 Ryan Dahl在这里插入图片描述把这V8搬到了服务器上,用于做服务器的软件。

Express框架

官方 : https://www.expressjs.com.cn/

Express : 基于 Node.js 平台,快速、开放、极简的 web 开发框架。

安装 : npm install express --save

   Router路由

  • 什么是路由 : 路由是指如何定义应用的端点(URIs)以及如何响应客户端的请求, 是由一个 URI、HTTP 请求(GET、POST等)和若干个句柄组成

  • 语法 : express(). methot (path, [callback…], callback).

    参数 METHOD是一个HTTP 请求方法 、path 是服务器上的路径、 callback 是当路由匹配时要执行的回调函数。

    演示 ↓

const express = require("express")

const app = express()

app.get("/", (req, res) => {
    res.send({
        name: "kerwin",
        age: 100
    })
})

app.listen(3000, () => {
    console.log("server start")
})

NEST 方法

next理解 : 使用next()放行,未使用next()不放行func2不执行 ↓

const express = require("express")

const app = express()

app.get("/", (req, res) => {
    res.send({
        name: "kerwin",
        age: 100
    })
})


//next()使用


const func1 = (req, res, next) => {
    // 验证用户token过期, cookie过期
    console.log("验证token")
    const isValid = true
    if (isValid) {
        res.text = "这是fun1计算的结果" //res携带参数
        next() //放行,未使用next()不放行func2不执行
    } else {
        //返回错误
        res.send("error")
    }
}
const func2 = (req, res) => {
    // 查询数据库
    // 返回内容
    console.log(res.text)
    res.send({ list: [1, 2, 3] })
}

app.get("/home", [func1, func2])

app.get("/list", [func1], (req, res) => {
    res.send("list")
})

app.listen(3000, () => {
    console.log("server start")
})

路由端点

路由端点:路由路径和请求方法一起定义了请求的端点,它可以是字符串、字符串模式或者正则表达式。

const express = require("express")

const app = express()

app.get('/',function(req,res){ //匹配根路径的请求
 res.send('root');
});

app.get('/random.text', function (req, res) {  //匹配/random.text路径的请求
    res.send('random.text');
});

app.get("/ab?cd", (req, res) => { //b可有可无
    res.send("ok")
})

app.get("/ab/:id/:id2", (req, res) => { //:id 表示可有是任意数值 :/ab/520/520
    res.send("ok")
})

app.get('/ab+cd', function (req, res) { //b+ 表示可有无数个b :/a bbbbbbbbbbb cd
    res.send('ab+cd');
});

app.get('/ab*cd', function (req, res) { //b* 表示可有无数个任意字符 如::/a babcdefc cd
    res.send('ab*cd');
});

app.get('/ab(cd)?e', function (req, res) { //cd可有可无
    res.send('ab(cd)?e');
});

app.get(/a/, function (req, res) { //匹配任何路径中含有a的路径
    res.send('/a/');
});

app.get(/.*fly$/, function (req, res) { //正则表达式 必须以fly为结尾
    res.send('/.*fly$/');
});

app.listen(3000, () => { //开启监听函数
    console.log("server start")
})

使用回调函数数组处理路由

var cb0 = function (req, res, next) {
    console.log('CB0')
    next()
}
var cb1 = function (req, res, next) {
    console.log('CB1')
    next()
}
var cb2 = function (req, res) {
    res.send('Hello from C!')
}
app.get('/example/c', [cb0, cb1, cb2])

使用混合使用函数和函数数组处理路由

var cb0 = function (req, res, next) {
    console.log('CB0')
    next()
}
var cb1 = function (req, res, next) {
    console.log('CB1')
    next()
}
app.get('/example/d', [cb0, cb1], function (req, res, next) {
    console.log('response will be sent by the next function ...')
    next()
}, function (req, res) {
    res.send('Hello from D!')
})

中间件的分类及用法

  • Express : Express 是一个自身功能极简,完全是由路由和中间件构成一个的 Web 开发框架 → 从本质上来说,一个 Express 应用就是在调用各种中间件。
  • 中间件 : 中间件(Middleware) 是一个函数,它可以访问请求对象(request object (req)), 响应对象(response object (res)), 和 web 应用中处于请求-响应循环流程中的中间件,一般被命名为 next 的变量。
  • 中间件的功能包括 ↓
    1. 执行任何代码。
    2. 修改请求和响应对象。
    3. 终结请求-响应循环。
    4. 调用堆栈中的下一个中间件。
  • Express 应用可使用如下几种中间件
    1. 应用级中间件
    2. 路由级中间件
    3. 错误处理中间件
    4. 内置中间件
    5. 第三方中间件
  • 注意: 如果当前中间件没有终结请求-响应循环,则必须调用 next() 方法将控制权交给下一个中间件,否则请求就会挂起。

   1、应用级中间件

说明 : 应用级中间件绑定到 app 对象 使用 app.use() 和 app.METHOD (), 其中, METHOD 是需要处理的HTTP 请求的方法,例如 GET, PUT, POST 等等,全部小写。

const express = require("express")
var app = express()
// 没有挂载路径的中间件,应用的每个请求都会执行该中间件
app.use(function (req, res, next) {
    console.log('Time:', Date.now())
    next()
})

小练

const express = require("express")
const app = express()

app.get("/", (req, res) => {
    res.send({
        name: "先生",
        age: 100
    })
})

const func1 = (req, res, next) => {
    // 验证用户token过期, cookie过期
    console.log("验证token")
    const isValid = true
    if (isValid) {
        res.text = "这是fun1计算的结果"
        next()
    } else {
        //返回错误
        res.send("error")
    }
}

app.use(func1) //这里使用了中间件  那么下代码必须执行中间件的验证后执行

const func2 = (req, res) => {
    // 查询数据库
    // 返回内容
    console.log(res.text)
    res.send({ list: [1, 2, 3] })
}

app.get("/home", [func2])
app.get("/list", (req, res) => {
    res.send("list")
})

app.listen(3000, () => {
    console.log("server start")
})

   2、路由级中间件

说明 : 路由级中间件和应用级中间件一样,只是它绑定的对象为 express.Router() (自定义模块)

  • 统一管理

服务器.js

const express = require("express")
const app = express()
const IndexRouter = require("./IndexRouter")
//应用级
app.use(function (req, res, next) {
    console.log("验证token")
    next()
})
//应用级
app.use("/api", IndexRouter)

app.listen(3000, () => {
    console.log("server start")
})

自定义模块

------IndexRouter------
const express = require("express")

const router = express.Router()
//应用级别
router.get("/home", (req, res) => {
    res.send("home")
})

router.get("/login", (req, res) => {
    res.send("login")
})

module.exports = router
  • 分类管理

服务器.js

const express = require("express")
const app = express()
const HomeRouter = require("./HomeRouter")
const LoginRouter = require("./LoginRouter")

//应用级
app.use(function (req, res, next) {
    console.log("验证token")
    next()
})

//应用级别
app.use("/home", HomeRouter)
app.use("/login", LoginRouter)

app.use((req, res) => {
    res.status(404).send("丢了")
})
app.listen(3000, () => {
    console.log("server start")
})

自定义模块 Router().js

------HomeRouter------
const express = require("express")

const router = express.Router()
//路由级别
router.get("/", (req, res) => {
    res.send("home")
})

router.get("/1", (req, res) => {
    res.send("home-1")
})

router.get("/2", (req, res) => {
    res.send("home-2")
})

module.exports = router


------LoginRouter------
const express = require("express")

const router = express.Router()
//路由级别
router.get("/", (req, res) => {
    res.send("login")
})

module.exports = router

   3、获取请求参数

  • 配置解析Post参数的-不用下载第三方 ,内置方法。

app.use(express.urlencoded({ extended: false }))
app.use(express.json())

post || get参数- username=kerwin&password=1234 //XXX & XXX
post参数- {name:“”,age:100} //JSON

get => req.query
post => req.body

------route------
const express = require("express")

const router = express.Router()

//路由级别-响应前端的get请求
router.get("/", (req, res) => {
    console.log(req.query)
    res.send("login-success")
})

路由级别-响应前端的post请求
router.post("/", (req, res) => {
    console.log(req.body)//必须配置中间件
    res.send({ ok: 1 })
})

module.exports = router

------index------
const express = require("express")
const app = express()
const LoginRouter = require("./route/LoginRouter")

//配置解析Post参数的-不用下载第三方 ,内置.
app.use(express.urlencoded({ extended: false })) //post参数- username=kerwin&password=1234 //XXX & XXX
app.use(express.json()) //post参数- {name:"",age:100} //JSON
//应用级别
app.use(function (req, res, next) {
    console.log("验证token")
    next()
})
//应用级别
app.use("/login", LoginRouter)

app.use((req, res) => {
    res.status(404).send("丢了")
})
app.listen(3000, () => {
    console.log("server start")
})

   4、错误处理中间件

  • 错误处理中间件和其他中间件定义类似,只是要使用 4 个参数,而不是 3 个,其签名如下: (err, req,res, next)。
app.use(function (err, req, res, next) {
    console.error(err.stack)
    res.status(500).send('Something broke!')
})

   5、内置中间件 静态资源

  • express.static 是 Express 唯一内置的中间件。它基于 serve-static,负责在 Express 应用中提托管静态资源。每个应用可有多个静态目录。

  • 托管静态资源的方法

    1. app.use(express.static(“public”))
app.use(express.static('public'))
app.use(express.static('uploads'))
app.use(express.static('files'))

练习

------login.html------
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div>
        <div>
            用户名:
            <input id="username" />
        </div>
        <div>
            密码:
            <input type="password" id="password" />
        </div>

        <div>
            <button id="login">登录-get</button>
            <button id="loginpost">登录-post</button>
        </div>
    </div>

    <script>

        var ologin = document.querySelector("#login")
        var ologinpost = document.querySelector("#loginpost")
        var username = document.querySelector("#username")
        var password = document.querySelector("#password")

        ologin.onclick = () => {
            //get请求
            fetch(`/login?username=${username.value}&password=${password.value}`).then(res => res.text()).then(res => {
                console.log(res)
            })
        }

        ologinpost.onclick = () => {
            //get请求
            fetch(`/login`, {
                method: "POST",
                body: JSON.stringify({
                    username: username.value,
                    password: password.value
                }),
                headers: {
                    "Content-Type": "application/json"
                }
            }).then(res => res.json()).then(res => {
                if (res.ok === 1) {
                    location.href = "/home.html" //(自己创1个)
                } else {
                    console.log("用户名密码不匹配")
                }
            })
        }
    </script>
</body>

</html>




------index------
const express = require("express")
const app = express()
const LoginRouter = require("./route/LoginRouter")

//配置静态资源
app.use(express.static("static"))

//配置解析post参数的-不用下载第三方 ,内置
app.use(express.urlencoded({ extended: false })) //post参数- username=kerwin&password=1234
app.use(express.json()) //post参数- {name:"",age:100}

//应用级别
app.use(function (req, res, next) {
    console.log("验证token")
    next()
})
//应用级别
app.use("/login", LoginRouter)

app.use((req, res) => {
    res.status(404).send("丢了")
})
app.listen(3000, () => {
    console.log("server start")
})




------LoginRouter------
```css
const express = require("express")

const router = express.Router()
//路由级别-响应前端的get请求
router.get("/", (req, res) => {
    console.log(req.query)
    res.send("login-success")
})

路由级别-响应前端的post请求
router.post("/", (req, res) => {
    console.log(req.body)//必须配置中间件
    const { username, password } = req.body
    if (username === "123" && password === "123") {
        res.send({ ok: 1 })
    } else {
        res.send({ ok: 0 })
    }
})
module.exports = router

   6、第三方中间件

  • 安装所需功能的 node 模块,并在应用中加载,可以在应用级加载,也可以在路由级加载。

  • cookie-parser

安装:$ npm install cookie-parser

使用 ↓

var express = require('express') //导入express
var app = express() //实例化express
var cookieParser = require('cookie-parser') //导入cookie

app.use(cookieParser()) //加载用于解析 cookie 的中间件

app.use('/', (req, res) => {
  console.log(req.cookies); //打印Cookies
  res.cookie(name,"郭先生!") //设置cookies
  next()
})

   7、服务端渲染(模板引擎)

  • 服务器渲染 与 前后端分离
  1. 服务器渲染 ,后端嵌套模板,后端渲染模板,SSR (后端页面组装)

    1、前端做好静态页面,动态效果。
    2、把前端代码提供给后端,后端把静态html以及里面的假数据删掉,通过模板进行动态生成html内容。
    3、使用中间件 ejs 实习后端渲染 , 安装命令 npm install ejs

  • ejs 语句

在这里插入图片描述

  • 使用 两步

    1. 配置view engine, 模板引擎,如: app.set(‘view engine’, ‘ejs’)
    2. 配置文件目录 app.set(‘views’, ‘./views’)
    3. 如果需要配置目录里面支持html,配置 app.engine(“html”, require(“ejs”).renderFile)
  • 代码演示

index.js------

const express = require("express")
const app = express()

const HomeRouter = require("./route/HomeRouter")
const LoginRouter = require("./route/LoginRouter")

//配置解析post参数的-不用下载第三方 ,内置
app.use(express.urlencoded({ extended: false })) //post参数- username=kerwin&password=1234
app.use(express.json()) //post参数- {name:"",age:100}

// 配置模板引擎
app.set("views", './views')
app.set("view engine", 'ejs')

//应用级别
app.use(function (req, res, next) {
    console.log("验证token")
    next()
})
//应用级别
app.use("/home", HomeRouter)
app.use("/login", LoginRouter)

app.use((req, res) => {
    res.status(404).send("404!")
})
app.listen(3000, () => {
    console.log("server start")
})


LoginRouter.js------

const express = require("express")
const router = express.Router()

//路由级别-响应前端的get请求
router.get("/", (req, res) => {
    // 渲染模板
    res.render("login", { error: "login", isShow: false })
})

//路由级别-响应前端的post请求
router.post("/", (req, res) => {
    let body = req.body
    if (body.username == "123" && body.userpassword == "123") {
        // 重定向
        res.redirect('home')
    } else {
        res.render("login", { error: "404", isShow: true })
        console.log(404);
    }
})
//路由级别-响应前端的put ,delete请求
module.exports = router

HomeRouter.js------

const express = require("express")
const router = express.Router()

//路由级别
router.get("/", (req, res) => {
    //假装这里是要替换的数据
    let list = ["小明", "小红", "小李"]
    //<%- %>练习 Html 会被浏览器解析
    let title = "<h1>一级标题</h1>"

    // render
    res.render('home', { name: "home", list, title })
})

module.exports = router

views文件夹

header.ejs 共功部分 ------

<header>
    <% if(isShowTitle) {%>
        <h1>校园招聘</h1>
        <% } %>
            <h1>我是公共头部</h1>
</header>


<style>
    header {
        background-color: red;
    }
</style>


home.ejs 首页部分------

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>
        <%= name%>
    </title>
</head>
<body>
    <h1>home</h1>

    <!-- <%- include%>() -->
    <h2><%- include("./common/header.ejs",{isShowTitle:false})%></h2>

    <ul>
        <% for (let i=0; i < list.length; i++) { %>
            <li>
                <%= list[i]%>
            </li>
            <% } %>
    </ul>

    <%# 解析 %>

        <h3>
            <%- title%>
        </h3>
</body>
<script>
</script>
</html>


login.ejs------

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>
        login
    </title>
</head>
<body>
    <h1>login</h1>
    <form action="./login" method="post">
        <div>用户名:<input type="text" name="username"></div>
        <div>密码:<input type="password" name="userpassword"></div>
        <div><input type="submit" value="登录"></div>
    </form>
    <h3>
        <%= isShow?'信息错误':''%>
    </h3>
</body>

</html>

Gir演示 ↓

在这里插入图片描述

  1. 前后端分离,BSR (前端组装页面)

    1、前端做好静态页面,动态效果
    2、使用Json 模拟,ajax,动态创建页面
    3、使用真实接口数据,前后联调
    4、前端提供给后端静态资源文件夹

  • 前端请求接口,后端返回对应的数据,前端获取数据渲染数据
login.html------

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div>
        <div>
            用户名:
            <input id="username" />
        </div>
        <div>
            密码:
            <input type="password" id="password" />
        </div>

        <div>
            <button id="login">登录-get</button>
            <button id="loginpost">登录-post</button>
        </div>
    </div>

    <script>

        var ologin = document.querySelector("#login")
        var ologinpost = document.querySelector("#loginpost")
        var username = document.querySelector("#username")
        var password = document.querySelector("#password")

		//前端请求接口Get Post ---------------------------

        ologin.onclick = () => {
            //get请求
            fetch(`http://127.0.0.1:3000/login?username=${username.value}&password=${password.value}`).then(res => res.text()).then(res => {
                console.log(res)
            })
        }

        ologinpost.onclick = () => {
            //post请求
            fetch(`http://127.0.0.1:3000/login`, {
                method: 'post',
                body: JSON.stringify({
                    username: username.value,
                    password: password.value
                }),
                headers: {
                    "Content-Type": "application/json"
                }
            }).then(res => res.json()).then(res => {
                if (res.ok === 1) {
                    location.href = "path"
                } else {
                    console.log("用户名密码不匹配")
                }
            })
        }
    </script>
</body>
</html>


index.js------

const express = require("express")
const app = express()
const LoginRouter = require("./route/LoginRouter")

//配置静态资源
app.use(express.static("public"))

//配置解析post参数的-不用下载第三方 ,内置
app.use(express.urlencoded({ extended: false })) //post参数- username=kerwin&password=1234
app.use(express.json()) //post参数- {name:"",age:100}

//应用级别
app.use(function (req, res, next) {
    console.log("验证token")
    next()
})
//应用级别
app.use("/login", LoginRouter)

app.use((req, res) => {
    res.status(404).send("请求出现错误❌")
})
app.listen(3000, () => {
    console.log("server start")
})


LoginRouter.js------

const express = require("express")
const router = express.Router()
//路由级别-响应前端的get请求
router.get("/", (req, res) => {
    res.setHeader('Access-Control-Allow-Origin', '*');
    //设置响应体
    res.setHeader('Access-Control-Allow-Headers', '*')
	//后端接受到请求返回对应的数据 
    res.send("login")
})

//路由级别-响应前端的post请求
router.all("/", (req, res) => {
    res.setHeader('Access-Control-Allow-Origin', '*');
    //设置响应体
    res.setHeader('Access-Control-Allow-Headers', '*')

    const { username, password } = req.body
    
	//后端接受到请求返回对应的数据 
    if (username === "123" && password === "123") {
        res.send({ ok: 1 })
    } else {
        res.send({ ok: 0 })
    }
})

//路由级别-响应前端的put ,delete请求
module.exports = router

   8、express生成器

express官网 : https://www.expressjs.com.cn/starter/generator

  • 使用步骤
    1. 局部安装 :npx express-generator
    2. 全局安装 :npm install -g express-generator
    3. 创建项目:npx express Name(高版本中)
    4. 运行项目 : npm run start → npm start
  • 注意jade模板对前端不太友好 → 使用 npx express myapp --view=ejs

图示 ↓

在这里插入图片描述

Node&MongoDB

  • 操作数据库模块 : npm install mongoose
  • Mongoose Npm : https://www.npmjs.com/package/mongoose

    第一步 连接数据库

//文件夹规范 config文件夹 → db.config.js

//连接数据库 通过Require导入模块链接数据库自动链接
const mongoose = require("mongoose")

const serverName = "MyDB"

//插入集合和数据,数据库serverName会自动创建
mongoose.connect(`mongodb://127.0.0.1:27017/${serverName}`).then(() => {
    console.log("数据库连接成功!");
})

    第二步 创建User Mongodb模型

//文件夹规范 modul文件夹 → UserModul.js

const mongoose = require("mongoose") //导入mongoose 以连接上了

//限制模型数据类型
const Schema = mongoose.Schema
const UserType = {
    username:String,
    password:String,
    age:Number
}

// 模型user 将会创建对应 users 集合
const UserModel = mongoose.model("user",new Schema(UserType))

module.exports = UserModel
  1. 返回UserModel方法使用

使用如 ↓

增加数据
UserModel.create({
    username,userpassword
})


查询数据
UserModel.find({username:"kerwin"},
["username","password"])
.sort({createTime:-1}).skip(10).limit(10)


更新数据
UserModel.updateOne({
    _id : ?
},{
    introduction,username,gender,avatar
})

删除数据
UserModel.deleteOne({_id})

    第三步 简单使用 Mongodb命令

客户端

<!DOCTYPE html>
<html>

<head>
  <title>
    Login客户端
  </title>
</head>

<body>
  <h1>mongodb的增删改查的演示</h1>
  <div>
    <div>用户名:<input id="username" /></div>
    <div>密码:<input type="password" id="password" /></div>
    <div>年龄:<input type="number" id="age" /></div>
    <div><button id="register">注册</button></div>
  </div>
  <hr>
  <div>
    <button id="update">更新</button>
    <button id="delete">删除</button>
  </div>
  <hr>

  <table border="1">
    <thead>
      <tr>
        <td>id</td>
        <td>用户名</td>
        <td>年龄</td>
      </tr>
    </thead>
    <tbody>
    </tbody>
  </table>

  <script>
    var register = document.querySelector("#register")
    var update = document.querySelector("#update")
    var deletebutton = document.querySelector("#delete")
    var username = document.querySelector("#username")
    var password = document.querySelector("#password")
    var age = document.querySelector("#age")

    //注册
    register.onclick = () => {
      fetch("/api/user/add", {
        method: "POST",
        body: JSON.stringify({
          username: username.value,
          password: password.value,
          age: age.value
        }),
        headers: {
          "Content-Type": "application/json"
        }
      }).then(res => res.json()).then(res => {
        console.log(res)
      })
    }

    //更新数据
    update.onclick = () => {
      fetch("/api/user/update/?", {
        method: "POST",
        body: JSON.stringify({
          username: "修改的名字",
          password: "修改的密码",
          age: 1
        }),
        headers: {
          "Content-Type": "application/json"
        }
      }).then(res => res.json()).then(res => {
        console.log(res)
      })
    }

    //删除数据
    deletebutton.onclick = () => {
      fetch("/api/user/delete/?").then(res => res.json()).then(res => {
        console.log(res)
      })
    }

    //渲染列表
    fetch("/api/user/list?page=1&limit=10").then(res => res.json()).then(res => {
      var tbody = document.querySelector("tbody")
      tbody.innerHTML = res.map(item => `
          <tr>
            <td>${item._id}</td>  
            <td>${item.username}</td>  
            <td>${item.age}</td>  
          </tr>
        `).join("")
    })
  </script>
</body>

</html>

服务器

//------用户注册接口 (插入数据)------  
app.post("/user/add",(req,res)=>{
//获取数据
  const {username,password,age} = req.body
  UserModel.create({
    username,password,age
  }).then(data=>{
    console.log(data) //成功获取的数据
    res.send({ //返回客户端数据
      ok:1
    })
  })
})

//------用户修改数据接口 (更新数据)------  
app.post("/user/update/:myid", (req, res) => {
  const { username, password, age } = req.body
  UserModel.updateOne({ _id: req.params.myid }, {
    username, age, password
  }).then(data => {
    res.send({ //返回客户端数据
      ok: 1
    })
  })
})

//------用户删除数据接口 (删除数据)------  
app.get("/user/delete/:myid", (req, res) => {
  UserModel.deleteOne({
    _id: req.params.myid
  }).then(data => {
    res.send({ //返回客户端数据
      ok: 1
    })
  })
})

//------获取列表 (列表数据渲染)------  
router.get("/user/list", (req, res) => {
  const { page, limit } = req.query //获取第几页 、 多少条数据
  UserModel.find({}, ["username", "age"]).sort({ age: -1 }).skip((page - 1) * limit).limit(limit).then(data => {
    res.send(data)
  })
})

    第四步 规范使用 Mongodb命令 (RESTful架构)

客户端

<!DOCTYPE html>
<html>

<head>
  <title>登录客户端</title>
</head>

<body>
  <h1>mongodb的增删改查的演示</h1>
  <div>
    <div>用户名:<input id="username" /></div>
    <div>密码:<input type="password" id="password" /></div>
    <div>年龄:<input type="number" id="age" /></div>
    <div><button id="register">注册</button></div>
  </div>
  <hr>
  <div>
    <button id="update">更新</but ton>
      <button id="delete">删除</button>
  </div>
  <hr>

  <table border="1">
    <thead>
      <tr>
        <td>id</td>
        <td>用户名</td>
        <td>年龄</td>
      </tr>
    </thead>
    <tbody>
    </tbody>
  </table>
  <script>

    var register = document.querySelector("#register")
    var update = document.querySelector("#update")
    var deletebutton = document.querySelector("#delete")
    var username = document.querySelector("#username")
    var password = document.querySelector("#password")
    var age = document.querySelector("#age")

    register.onclick = () => {
      fetch("/api/user", {
        method: "POST",
        body: JSON.stringify({
          username: username.value,
          password: password.value,
          age: age.value
        }),
        headers: {
          "Content-Type": "application/json"
        }
      }).then(res => res.json()).then(res => {
        console.log(res)
      })
    }

    update.onclick = () => {
      fetch("/api/user/?", {
        method: "PUT",
        body: JSON.stringify({
          username: "修改的名字",
          password: "修改的密码",
          age: 1
        }),
        headers: {
          "Content-Type": "application/json"
        }
      }).then(res => res.json()).then(res => {
        console.log(res)
      })
    }

    deletebutton.onclick = () => {
      fetch("/api/user/?", {
        method: "DELETE"
      }).then(res => res.json()).then(res => {
        console.log(res)
      })
    }

    //获取列表
    fetch("/api/user?page=1&limit=10").then(res => res.json()).then(res => {
      var tbody = document.querySelector("tbody")
      tbody.innerHTML = res.map(item => `
          <tr>
            <td>${item._id}</td>  
            <td>${item.username}</td>  
            <td>${item.age}</td>  
          </tr>
        `).join("")
    })
  </script>
</body>

</html>

服务器

//相应前端的post请求-增加用户
router.post("/user", (req, res) => {
  const { username, password, age } = req.body
  UserModel.create({
    username, password, age
  }).then(data => {
    console.log(data) //成功获取的数据
    res.send({ //返回客户端数据
      ok: 1
    })
  })
})

//------用户修改数据接口 (更新数据)------  
//动态路由, 获取ID
router.put("/user/:myid", (req, res) => {
  const { username, age, password } = req.body
  UserModel.updateOne({ _id: req.params.myid }, {
    username, age, password
  }).then(data => {
    res.send({//返回客户端数据
      ok: 1
    })
  })
})

//------用户删除数据接口 (删除数据)------  
router.delete("/user/:myid", (req, res) => {
  UserModel.deleteOne({
    _id: req.params.myid
  }).then(data => {
    res.send({//返回客户端数据
      ok: 1
    })
  })
})

//------获取列表 (列表数据渲染)------  
router.get("/user", (req, res) => {
  const { page, limit } = req.query
  UserModel.find({}, ["username", "age"]).sort({ age: -1 }).skip((page - 1) * limit).limit(limit).then(data => {
    res.send(data)
  })
})

总结

以上是个人学习Node的相关知识点,一点一滴的记录了下来,有问题请评论区指正,共同进步,这才是我写文章的原因之,如果这篇文章对您有帮助请三连支持一波

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/589153.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用 python 制作自动填写问卷星问卷调查程序

目录 前言环境&#xff1a;代码展示尾语 &#x1f49d; 前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 你的问卷星任务还没做完吗&#xff1f;今天教你如何快速把问卷星调查任务给完成。 环境&#xff1a; anaconda5.2.0&#xff08;python3.6.8&#xff09; 编辑器: p…

ASEMI代理KY可控硅BT169的工作原理及应用领域

编辑-Z 本文主要介绍了可控硅BT169的工作原理及其在各个领域的用。首先&#xff0c;我们将详细阐述可控硅BT169的工作原理&#xff0c;包括结构特点、工作过程等&#xff1b;其次&#xff0c;我们将探讨可控硅BT169在家用电器、工业控制、电力电子等领域的应用。 1、可控硅BT1…

RSA加密 多线程读写不安全

转自&#xff1a;&#xff08;一场开源 RSA 库引发的“血案”&#xff09; 导读 RSA 加密算法是一种非对称加密算法&#xff0c;该算法极为可靠&#xff0c;在现有技术条件下&#xff0c;很难破解&#xff0c;因此在软件开发中被广泛使用。你不必担心&#xff0c;本文不会介绍…

如何Debug调试Android程序

当开发过程中遇到一些奇怪的bug&#xff0c;但又迟迟定位不出来原因是什么的时候&#xff0c;最好的解决办法就是调试了。调试允许我们逐行地执行代码&#xff0c;并可以实时观察内存中的数据&#xff0c;从而能够比较轻易地查出问题的原因。总结一下使用Android Studio来调试A…

又双叒添新证书:上海斯歌通过ISO9001和ISO27001认证

近期&#xff0c;上海斯歌顺利通过权威机构审查&#xff0c;正式成为ISO9001质量管理体系和ISO27001信息管理安全体系双重认证企业。 可以说ISO9001及ISO27001的认证&#xff0c;既是斯歌坚持管理标准化、程序化、规范化的成果&#xff1b;也是国际标准化组织&#xff08;ISO&a…

Vue3通透教程【十六】TS自动编译

文章目录 &#x1f31f; 写在前面&#x1f31f; 自动编译&#x1f31f; 编译器的配置文件&#x1f31f; 写在最后 &#x1f31f; 写在前面 专栏介绍&#xff1a; 凉哥作为 Vue 的忠实 粉丝输出过大量的 Vue 文章&#xff0c;应粉丝要求开始更新 Vue3 的相关技术文章&#xff0…

Apache的配置与应用(构建web、日志分割及AWStats分析系统)

Apache的配置与应用 一、构建虚拟Web主机二、httpd服务支持的三种虚拟机类型1、基于域名的虚拟主机2、基于IP地址的虚拟主机3、基于端口的虚拟主机 三、构建web虚拟目录与用户授权限制1、创建用户认证数据文件2、添加用户授权配置3、验证用户访问权限4、在客户机中浏览器访问 四…

F牌独立站都有哪些收款方式?各有什么优缺点?

最近几个月以来&#xff0c;FP独立站的收款支付问题变得非常焦灼&#xff0c;不少跨境卖家忧心忡忡&#xff0c;害怕自己收不了款血本无归。今天&#xff0c;我跟大家介绍几种FP独立站的收款方式&#xff0c;以及解析他们各有哪些优缺点&#xff0c;方便卖家选择。 一、TT电汇 …

Go GPM 调度器介绍

Go GPM 调度器介绍 1 简介 ​ 这几天在学习Go的GPM机制&#xff0c;于是就整理了一下收集的资料分享给大家&#xff0c;文章末尾有原文链接。主要介绍了Go在运行时调度器的基本实现逻辑和演变过程。 ​ 2 什么是Go调度器 ​ Go调度器很轻量也很简单&#xff0c;足以撑起gorout…

数据结构基础-数组

2.1 数组 概述 定义 在计算机科学中&#xff0c;数组是由一组元素&#xff08;值或变量&#xff09;组成的数据结构&#xff0c;每个元素有至少一个索引或键来标识 In computer science, an array is a data structure consisting of a collection of elements (values or v…

在 Linux 中启动时自动启动 Docker 容器的 2 种方法

Docker 是一种流行的容器化平台&#xff0c;允许开发人员将应用程序及其依赖项打包成一个独立的容器&#xff0c;以便在不同环境中运行。在 Linux 系统中&#xff0c;我们可以通过配置来实现在系统启动时自动启动 Docker 容器。本文将详细介绍两种方法&#xff0c;以便您了解如…

软件测试面试了一个00后,让我见识到了什么是内卷届的天花板

公司前段缺人&#xff0c;也面了不少测试&#xff0c;结果竟然没有一个合适的。一开始瞄准的就是中级的水准&#xff0c;也没指望来大牛&#xff0c;提供的薪资也不低&#xff0c;面试的人很多&#xff0c;但平均水平很让人失望。令我印象最深的是一个00后测试员&#xff0c;他…

Android bitmap保姆级教学

1. 认识Bitmap Bitmap是一个final类&#xff0c;因此不能被继承。Bitmap只有一个构造方法&#xff0c;且该构造方法是没有任何访问权限修饰符修饰&#xff0c;也就是说该构造方法是friendly&#xff0c;但是谷歌称Bitmap的构造方法是private&#xff08;私有的&#xff09;&am…

【C++】this 指针的概念

欢迎来到博主 Apeiron 的博客&#xff0c;祝您旅程愉快 &#xff01; 时止则止&#xff0c;时行则行。动静不失其时&#xff0c;其道光明。 目录 1、缘起 2、this 指针的用途 2.1、用途 1 2.1.1 解法 1 2.1.2 解法 2 2.2、用途 2 2.3、用途 3 3、总结 1、缘起 我…

网络编程_TCP/IP四层协议分层

网络编程_TCP/IP四层协议分层 1. OSI七层协议模型 (open system interconnection)与TCP/IP四层协议分层2. 协议封装3. TCP 协议头部4.三次握手5.滑动窗口正常情况丢包情况 6.四次挥手 1. OSI七层协议模型 (open system interconnection)与TCP/IP四层协议分层 OSI七层协议模型 (…

珞珈一号夜间灯光数据校正流程

一、前言 随着珞珈一号夜间灯光数据的发射,其高分辨率等优异性能,可以为我国相关部门监测国内和全球宏观经济运行情况,为政府决策提供客观依据,珞珈一号理想情况下荷在15天内完成绘制全球夜光影像,提供我国或者全球GDP指数、碳排放指数、城市住房空置率指数等专题产品。 …

larvael dcat-admin 表单设置自定义样式

表单有些不是自己想要的样式想要覆写或者增加 可以如下 public function form() {​​​​​​​$this->column(6, function () {$this->dateRange(order_created_at.start, order_created_at.end)->label(下单时间)->setLabelClass([input-group]) // 设置样式-&…

盘点几个实现VLAN间路由的好方法

在真实的网络中&#xff0c;常常需要跨VLAN通信。 许多网络工作者通常选择一些方法来实现不同VLAN中的主机之间的相互访问&#xff0c;如单臂路由。 然而&#xff0c;由于单臂路由技术的一些限制&#xff0c;如带宽和转发效率&#xff0c;这种技术是很少使用。 三层交换机在…

SpringBoot 集成WebSocket详解

感谢参考文章的博主&#xff0c;关于WebSocket概述和使用写的都很详细&#xff0c;这里结合自己的理解&#xff0c;整理了一下。 一、WebSocket概述 1、WebSocket简介 WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器…

一文详解 Sa-Token 中的 SaSession 对象

Sa-Token 是一个轻量级 java 权限认证框架&#xff0c;主要解决登录认证、权限认证、单点登录、OAuth2、微服务网关鉴权 等一系列权限相关问题。 Gitee 开源地址&#xff1a;https://gitee.com/dromara/sa-token 本文将详细介绍 Sa-Token 中的不同 SaSession 对象的区别&#x…