Node.js基础:从入门到实战

初识 Node.js 与内置模块

(初识)
1、知道什么是node.js
2、知道node.js可以做什么
3、node.js 中js的组成部分
(内置模块)
4、用 fs 模块读写操作文件
5、使用 path 模块处理路径
6、使用http 模块写一个基本的web服务器

初识 Node.js

回顾与思考

回忆浏览器中的 JavaScript 组成:

在这里插入图片描述

为什么JavaScript可以在浏览器中被执行,是因为浏览器中存在JavaScript解析引擎,而不同的浏览器使用的解析引擎是不一样的:

在这里插入图片描述

在这里插入图片描述

因此可以总结出 JavaScript 的运行环境就包括下面两个部分:

在这里插入图片描述

由上述内容我们可以总结出两点:

1、V8 引擎负责解析和执行 JavaScript 代码

2、内置 API 是由运行环境提供的特殊接口,只能在所属的运行环境中被调用

那么 JavaScript 能否做后端开发呢?

在这里插入图片描述

当然是没有问题的,JavaScript 本身只是一门语言,这门语言所编写出来的代码想要执行的话离不开运行时环境,如果将 JavaScript 的代码放在浏览器里运行那么浏览器本身就是一个运行时环境,此时 JavaScript 就可以用来做前端开发,同时如果我们将 JavaScript 代码放在 Node.js 环境(Node.js 也是一个 JavaScript 的运行时环境,只不过是一个后端的运行时环境)当中,通过 Node.js 就可以让我们的 JavaScript 去做后端开发了。

Node.js 简介

先来看一段官方的介绍:

在这里插入图片描述

为什么是基于 Chrome V8 呢?之前说过,因为它最牛逼。所以使用 V8 来做 Node.js 的引擎用以解析 JavaScript 的代码,这样可以让 JavaScript 跑的更快。

所以我们的 Chrome 浏览器和 Node.js 用的是同一款 JavaScript 解析引擎,即 V8 ;

只不过 V8 用在不同的地方做的事情是不一样的,在 Chrome 浏览器中用 V8 解析 JavaScript 做的是前端的开发,而在 Node.js 中使用 V8 解析 JavaScript 则做的是后端开发,仅此而已。

Node.js 的运行时环境

在这里插入图片描述

可以看见,Node.js 为我们提供了后端开发所需要的所有模块的 API,因此学习 Node.js 很大程度上就是学习怎么使用这些内置的后端开发的 API。

Node.js 可以做什么

在这里插入图片描述

一句话,全栈!

Node.js 怎么学

在这里插入图片描述

Node.js 环境的安装

在这里插入图片描述

官方网址:Node.js

在这里插入图片描述

直接下载完成后双击安装即可,一路按照默认的来就行。

检测安装是否成功,打开 cmd 命令终端输入 node -v,能正常显示版本号即正常:

在这里插入图片描述

这样就安装完成了。

什么是终端

在这里插入图片描述

在 Node.js 环境中执行 JavaScript 代码

下面介绍的是比较朴素的方式,因为现在都使用 IDE 了,我用的是 WebStorm,比较推荐,IDE 的使用就不介绍了,网上很多,不再赘述。

就两步:

在这里插入图片描述

先来写一个 1.js 文件:

在这里插入图片描述

然后进入终端,在当前文件目录的命令行下,用 node 命令启动即可:

在这里插入图片描述

这样就可以运行 JavaScript 代码啦。

有一种便捷打开命令行的方式,即在我们的文件目录下,按住 shift 后点击鼠标右键会有一个打开 PowerShell 的选项:

在这里插入图片描述

点击它:

在这里插入图片描述

可以看见这种方式更加的快捷,那么 PowerShell 和我们之前的 CMD 方式有什么区别呢?

CMD 方式是出现的比较早的一种方式,是旧版本的 windows 里的终端,后来 windows 做了升级,改成了 PowerShell ,也就是新版本的 CMD(其实用哪个都行,但是 PowerShell 的功能更加强大一些)。

终端中常用的一些快捷键:

在这里插入图片描述

使用WebStorm编写 Node.js 代码没有提示问题解决

参考这篇文章:使用WebStorm编写 Node.js 代码没有提示问题解决

fs 文件系统模块

什么是 fs 文件系统模块

在这里插入图片描述

我们只需要知道在安装 Node.js 的时候这些模块就都被安装到电脑本地了即可,然后需要用到哪个模块,就使用 require 方法将其导入进来即可。

读取指定文件中的内容

fs.readFile() 的语法格式

在这里插入图片描述

示例代码如下:

// 1、到入 fs 模块操作文件
const fs = require('fs')

//2、调用 fs.readFile() 方法读取文件
// 参数1、 读取文件的存放路径
// 参数2、 读取文件时候采用的编码格式,一般默认指定 utf8
// 参数3、 回调函数,拿到读取失败和成功的结果,err dataStr
fs.readFile('./1.txt', 'utf8', function (err, dataStr){
    // 打印失败的结果
    // 如果读取成功,则err 的值为null
    // 如果读取失败,则 err 的值为错误对象,dataStr 的值为 undefined
    // 因此可以通过判断 err 对象是否为 null,来判断文件读取是否成功
    console.log(err)
    console.log("----------------")
    // 打印成功的结果
    // 如果读取成功,那么dataStr就是从文件当中读取的值
    // 如果读取失败,那么dataStr就是undefined
    console.log(dataStr)
})

运行结果如下:

在这里插入图片描述

关于fs.readFile()第三个参数是回调函数的解释:
fs.readFile('./1.txt', 'utf8', function (err, dataStr){
    console.log(err)
    console.log("----------------")
    console.log(dataStr)
})

这段代码中的回调函数是作为 fs.readFile 方法的最后一个参数传递进去的。根据 Node.js 中的约定,回调函数的第一个参数通常用于表示错误信息,第二个参数则是成功时返回的数据或结果(这是 fs.readFile() 函数的形式约定)。

所以,当你使用 fs.readFile 方法时,如果文件读取成功,Node.js 会将 err 参数置为 null,而将文件内容作为 dataStr 参数传递给回调函数;如果文件读取失败,Node.js 会将 err 参数设置为相应的错误对象,而 dataStr 则会是 undefined。

因此,通过检查 err 参数是否为 null,你可以轻松地判断文件读取是否成功。如果 err 为 null,则表示读取成功,可以在 dataStr 中访问文件内容;如果 err 不为 null,则表示读取失败,dataStr 会是 undefined,同时你可以查看 err 对象来了解具体的错误信息。

向指定的文件中写入内容

fs.writerFile()的语法格式

在这里插入图片描述

示例代码如下:

const fs = require('fs')

fs.writeFile('./2.txt', 'abcd', 'utf8', function (err){
	// 如果文件写入成功,则 err 的值等于 null
	// 如果文件写入失败,则 err 的值等于一个错误对象
    console.log(err)
})

运行结果如下:

在这里插入图片描述

因为运行成功,因此 err 是 null 值。

fs 模块 - 路径动态拼接的问题

在这里插入图片描述

出现路径拼接错误的问题,是因为提供了 ./ 或者 …/ 开头的相对路径。

如果要解决这个问题,可以直接提供一个完整的文件存放路径(即绝对路径)即可。

但是这又会带来一种新的问题,就是代码的移植性非常差,不利于维护。

那么如何完美解决这个问题呢?可以使用 Node.js 给我们提供的 __dirname 参数:

在这里插入图片描述

测试也比较简单,打印出来即可知道 __dirname 就是代表当前文件所处的目录,因此不再赘述。

path 路径模块

什么是 path 路径模块

在这里插入图片描述

路径拼接

path.join() 的语法格式

在这里插入图片描述

代码示例如下:

const path = require('path')

// 注意:../ 会抵消前面的路径
const pathStr = path.join('/a','/b/c','../','./d','e')

console.log(pathStr) // 输出:\a\b\d\e

//今后凡是涉及到路径拼接的操作,都要使用 path.join() 方法进行处理。
// 不要用 + 进行字符串拼接
const pathFile = path.join(__dirname, '/a/1.txt')

console.log(pathFile)

运行结果如下:

在这里插入图片描述

获取路径中的文件名

path.basename() 的语法格式

在这里插入图片描述

示例代码:

const path = require('path')

//定义文件的存放路径
const fpath = '/a/b/c/index.html'

const fullName = path.basename(fpath)
console.log(fullName) //输出:index.html


const nameWithoutExt = path.basename(fpath, '.html')
console.log(nameWithoutExt) //输出:index

运行结果如下:

在这里插入图片描述

获取路径中的文件扩展名

path.extname() 的语法格式

在这里插入图片描述

示例代码如下:

const path = require('path')

//这是文件的存放路径
const fpath = '/a/b/c/index.html'

const fext = path.extname(fpath)

console.log(fext)

运行结果如下:

在这里插入图片描述

关于 path 模块需要注意的两个小点

在这里插入图片描述

http 模块

什么是 http 模块

在这里插入图片描述

进一步理解 http 模块的作用:

在这里插入图片描述

创建最基本的 web 服务器

在这里插入图片描述

上面的步骤细分下来其实就是下面这样:

第一步:导入 http 模块

在这里插入图片描述

第二步:创建 web 服务器实例

在这里插入图片描述

第三步:为服务器实例绑定 request 事件

在这里插入图片描述

第四步:启动服务器

在这里插入图片描述

接下来我们来代码实操一下:

//1、导入 http模块
const http = require('http')
//2、创建 web 服务器实例
server = http.createServer()
//3、为服务器实例绑定 request 事件,监听客户端的请求
server.on('request', function (req, res){
    console.log('Someone visit our web server.')
})
//4、启动服务器
server.listen(80,function (){
    console.log('Server running at http://127.0.0.1')
})

运行效果如下:

在这里插入图片描述

在这里插入图片描述

可以发现当我们在浏览器访问该地址的时候,我们的监听事件已经监听到了事件。

补充:什么是箭头函数

这是 JavaScript 中的箭头函数语法。()=>{} 是一个简单的箭头函数,它表示一个没有参数的函数,并返回一个空对象(即函数体内没有执行任何操作)。箭头函数是 ES6(ECMAScript 2015)中引入的一种新的函数声明方式,它可以更简洁地定义函数,并且在一些情况下具有更清晰的语义。

req 请求对象

在这里插入图片描述

代码示例如下:

const http = require('http')
server = http.createServer()
// req 是请求对象,包含了与客户端相关的数据和属性
server.on('request', (req)=>{
    // req.url 是客户端请求的 url 地址
    const url = req.url
    //req.method 是客户端请求的 method 类型
    const method = req.method
    const str = `Your request url is ${url}, and request method is ${method}`
    console.log(str)
})

server.listen(80,function (){
    console.log('Server running at http://127.0.0.1')
})

运行效果如下:

在这里插入图片描述

在这里插入图片描述

res 响应对象

在这里插入图片描述

示例代码如下:

const http = require('http')
server = http.createServer()
// req 是请求对象,包含了与客户端相关的数据和属性
server.on('request', (req, res)=>{
    // req.url 是客户端请求的 url 地址
    const url = req.url
    //req.method 是客户端请求的 method 类型
    const method = req.method
    const str = `Your request url is ${url}, and request method is ${method}`
    console.log(str)
    // 调用 res.end() 方法向客户端响应一些内容
    res.end(str)
})

server.listen(80,function (){
    console.log('Server running at http://127.0.0.1')
})

运行效果如下:

在这里插入图片描述

解决中文乱码的问题

在这里插入图片描述

代码示例如下:

const http = require('http')
server = http.createServer()
// req 是请求对象,包含了与客户端相关的数据和属性
server.on('request', (req, res)=>{
    // req.url 是客户端请求的 url 地址
    const url = req.url
    //req.method 是客户端请求的 method 类型
    const method = req.method
    const str = `你的请求路径是 ${url}, 请求方法是 ${method}`
    console.log(str)
    // 发送数据前设置响应头,设置编码方式
    res.setHeader('Content-Type', 'text/html; charset=utf-8')
    // 调用 res.end() 方法向客户端响应一些内容
    res.end(str)
})

server.listen(80,function (){
    console.log('Server running at http://127.0.0.1')
})

运行效果如下:

在这里插入图片描述

根据不同的 url 响应不同的 html 内容

在这里插入图片描述

动态响应内容的代码示例:

const http = require('http')

server = http.createServer()

// req 是请求对象,包含了与客户端相关的数据和属性
server.on('request', (req, res)=>{
    //1、获取请求的 url 地址
    const url = req.url
    //2、设置默认的响应内容为 404 Not Found
    let content = '404 Not Found'
    //3、判断用户请求的是否为 / 或者 /index.html 页面
    //4、判断用户请求的是否为 /about.html 关于页面
    if(url === '/' || url === '/index.html'){
        content = '<h1>首页</h1>'
    }else if(url === '/about.html'){
        content = '<h1>关于页面</h1>'
    }
    //5、设置 Content-Type 响应头,防止中文乱码
    res.setHeader('Content-Type', 'text/html; charset=utf-8')
    //6、使用 res.end() 把内容响应给客户端
    res.end(content)
})

server.listen(80,function (){
    console.log('Server running at http://127.0.0.1')
})

运行效果如下:

在这里插入图片描述

在这里插入图片描述

补充:${} 模板字符串语法

${} 是 JavaScript 中的模板字符串语法。在字符串中使用 ${} 可以插入变量或表达式的值。在这种情况下,${url} 表示将变量 url 的值插入到字符串中。这种语法使得字符串拼接更加清晰和简洁。

模块化

在这里插入图片描述

模块化的基本概念

模块化是指解决一个复杂问题时,自顶向下逐层把系统划分为若干模块的过程。对于整个系统来说,模块是可组合、分解和更换的单元。

在这里插入图片描述

模块化规范

在这里插入图片描述

Node.js 中模块的分类

在这里插入图片描述

加载模块

在这里插入图片描述

注意:在使用 require 加载用户自定义模块期间,可以省略 .js 的后缀名。

Node.js 中的模块作用域

在这里插入图片描述

模块作用域的好处就是:防止了全局变量污染的问题。

向外共享模块作用域中的成员

module 对象

在这里插入图片描述

module.exports 对象

在这里插入图片描述

接下来我们用代码来解释一下。

先创建两个自定义模块,一个是自定义模块.js 另一个是 test.js,然后我们 自定义模块.js 文件先不写任何内容,在 test.js 中先去 require 自定义模块.js 中的内容试一下:

在这里插入图片描述

运行效果如下:

在这里插入图片描述

可以看见打印不出任何内容,因为我们在导入另一个模块的时候,我们导入的其实是另一个模块 module 的 exports 属性,默认情况下 exports 属性就是空的,这可以从上一小节讲的 module 对象 中的图里看到。

因此我们其实可以在 自定义模块.js 中对外共享一些本模块中的成员:

在这里插入图片描述

此时我们在运行 test.js 查看现在是否 modules.export 为空了:

在这里插入图片描述

可以看见不为空了,有内容的。

共享成员时的注意点

在这里插入图片描述

exports 对象

在这里插入图片描述

代码验证如下:

console.log(exports)
console.log(module.exports)
console.log(exports === module.exports)

运行效果如下:

在这里插入图片描述

exports 和 module.exports 的使用误区

在这里插入图片描述

Node.js 中的模块化规范

在这里插入图片描述

npm 与包

什么是包

在这里插入图片描述

包的来源

在这里插入图片描述

为什么需要包

在这里插入图片描述

从哪里下载包

在这里插入图片描述

如何下载包

在这里插入图片描述

查看自己电脑上的 npm 版本:

在这里插入图片描述

npm 初体验

在这里插入图片描述

这种传统方法就不演示了,可以看出来很繁琐,因此我们直接使用第三方包来完成一样的事情:

在这里插入图片描述

在项目中安装包的命令

在这里插入图片描述

接下来我们来演示如何用 npm 下载 第三方包,这里我直接使用 WebStorm 的终端进行下载了:

在这里插入图片描述

可以看见此时就已经下载安装好了。

写代码来实现我们的时间格式化操作:

//1、导入需要的包
const moment = require('moment')

//2、查阅官方文档明白第三方包要如何使用
const dt = moment().format('YYYY-MM-DD HH:mm:ss')
console.log(dt)

运行效果如下:

在这里插入图片描述

初次安装后都多了哪些文件

在这里插入图片描述

可以检查一下自己的项目:

在这里插入图片描述

注意:程序员不要手动修改 node_modules 或者 package-lock.json 文件中的任何代码,npm 包管理工具会自动维护它们。

安装指定版本的包

在这里插入图片描述

注意:如果我们要切换第三方包的版本并不需要先卸载我们现有版本的包,而是直接下新的即可,新的会覆盖原来旧版本的包嗷。

包的语义化版本规范

在这里插入图片描述

包管理配置文件

在这里插入图片描述

多人协作的问题

在这里插入图片描述

如何记录项目中安装了哪些包

在这里插入图片描述

快速创建 package.json

在这里插入图片描述

dependencies 节点

在这里插入图片描述

一次性安装所有的包

在这里插入图片描述
在这里插入图片描述

卸载包

在这里插入图片描述

devDependencies 节点

在这里插入图片描述

怎么知道哪些第三方包需要被保存到 devDependencies 哪些需要被保存到 dependencies 呢?

这些其实在官方文档都会有说的,查阅官方文档就行。

为什么下包速度慢

在这里插入图片描述

下包速度慢解决:淘宝 NPM 镜像服务器

在这里插入图片描述

切换 NPM 的下包镜像源

在这里插入图片描述

nrm 小工具

在这里插入图片描述

包的分类

使用 npm 包管理工具下载的包,共分为两大类,分别是:项目包和全局包。

在这里插入图片描述

在这里插入图片描述

好用的第三方包:i5ting_toc

在这里插入图片描述

规范的包结构

在这里插入图片描述

package.json 为啥必须要包含 main 包入口的这个属性呢?

这是因为在我们项目中使用 require 导入第三方包的时候其实走的就是这个 main 属性,通过这个 main 属性我们才能正常使用这个包的功能,即它是包的入口。

开发属于自己的包

假设我们现在需要开发的包叫 itheima-tools 包,其需要实现下面的功能:

在这里插入图片描述

那么接下来我们就按照下面的步骤开发我们自己的包:

在这里插入图片描述

实现效果如下:

在这里插入图片描述

然后初始化 package.json :

在这里插入图片描述

如果你使用 WebStorm 进行文件创建的话,可以发现其是自动生成的,只要点击创建就可以了。

不难发现这个 package.json 包其实就是一个 json 配置对象:

在这里插入图片描述

但是我们需要改一下,改成 PPT 中的那样,否则没办法发布到 NPM 的服务器上:

在这里插入图片描述

上面需要解释的几个含义:

main:就是入口文件的位置
keywords:这是被发布到 npm 服务器上时别人可以检索到这个包所使用的关键字有哪些
license:所遵循的开源许可协议,npm 官方推荐使用 ISC,因此我们用这个即可

然后编写我们的包源码:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

将不同的功能进行模块化拆分

在这里插入图片描述

src 是我们的新创建的源码文件夹,拆分的部分将全部放进该文件夹中。

编写包的说明文档

在这里插入图片描述

发布包

主要有以下几个步骤:

在这里插入图片描述

在这里插入图片描述

注意:在运行 npm login 命令之前,必须先把下包的服务器地址切换为 npm 的官方服务器。否则会导致发布包失败!

在这里插入图片描述

删除已发布的包

在这里插入图片描述

模块的加载机制

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

Express.js

在这里插入图片描述

初识 Express.js

Express.js 简介

在这里插入图片描述

进一步理解 Express

在这里插入图片描述

Express 能做什么

在这里插入图片描述

Express 安装

在这里插入图片描述

这里看的课的老师用的 4.17.1 的版本,我看了一下现在官网的最新版本是 4.19.2:

按照包的语义化版本规范,因为是只上升了第二位数的大小,说明相较于 4.17.1 的版本,现在最新的版本也只不过是新增了一些功能并且修复了一点 bug 而已,因此我们直接安装使用最新版即可:

在这里插入图片描述

查看版本:

在这里插入图片描述

Express 创建 web 服务器

在这里插入图片描述

来实现一下:

// 1、导入 Express
const express = require('express')
// 2、创建 web 服务器
const app = express()
// 3、启动 web 服务器
// 调用 app.listen(端口号,启动成功后的回调函数),启动服务器
app.listen(80, ()=>{
    console.log('express server running at http://127.0.0.1')
})

运行效果如下:

在这里插入图片描述

Express 监听 Get 和 Post 请求

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

示例代码如下:

// 1、导入 Express
const express = require('express')
// 2、创建 web 服务器
const app = express()

//4、监听客户端的 Get 和 Post 请求,并向客户端响应具体的内容
app.get('/user',(req,res) => {
    //调用 express 提供的 res.send() 方法,向客户端响应一个 JSON 对象
    res.send({
        name: 'zs',
        age : 20,
        gender: '男'
    })
})

app.post('/user',(req,res) => {
    //调用 express 提供的 res.send() 方法,向客户端响应一个文本字符串
    res.send('请求成功')
})

// 3、启动 web 服务器
app.listen(80, ()=>{
    console.log('express server running at http://127.0.0.1')
})

效果如下:

在这里插入图片描述

获取 URL 中携带的查询参数

在这里插入图片描述

示例代码如下:

app.get('/', (req,res)=>{
    //通过 req.query 可以获取到客户端发送过来的 查询参数
    //注意:默认情况下,req.query 是一个空对象
    console.log(req.query)
    res.send(req.query)
})

运行结果如下:

在这里插入图片描述

此时我们加上查询参数运行结果将变为:

在这里插入图片描述

获取 URL 中的动态参数

在这里插入图片描述

示例代码如下:

//注意:这里的 :id 是一个动态的参数
app.get('/user/:id',(req,res)=>{
    // req.params 是动态匹配到的 URL 参数,默认是空对象
    console.log(req.params)
    res.send(req.params)
})

运行效果如下:

在这里插入图片描述

我们不止可以写一个,可以写多个动态参数:

//注意:这里的 :id 是一个动态的参数
app.get('/user/:id/:name',(req,res)=>{
    // req.params 是动态匹配到的 URL 参数,默认是空对象
    console.log(req.params)
    res.send(req.params)
})

运行效果如下:

在这里插入图片描述

托管静态资源

express.static()

在这里插入图片描述

简单测试一下:

在这里插入图片描述

运行效果如下:

在这里插入图片描述

托管多个静态资源目录

在这里插入图片描述

挂载路径前缀

在这里插入图片描述

调试工具:nodemon 的安装与使用

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

Express 路由

什么是路由

广义上讲,路由就是映射关系。

比如:

在这里插入图片描述

在上图中,路由就是按键与服务之间的映射关系。

Express 中的路由

在这里插入图片描述

实际项目中的示例程序:

在这里插入图片描述

路由的匹配过程

在这里插入图片描述

路由的使用

在这里插入图片描述

这种方式之前就用过很多次了,只要知道有这种用法即可,实际的项目中我们不会采用这么直接的方式,因此不再赘述。

模块化路由

在这里插入图片描述

创建路由模块

在这里插入图片描述

我们新创建一个 router.js 模块,也就是一个自定义模块,在其内部创建和挂载我们的路由模块:

// 这是路由模块

//1、导入 express
const express = require('express')
//2、创建路由对象
const router = express.Router()
//3、挂载具体的路由
router.get('/user/list',(req,res) => {
    res.send('Get user list')
})

router.post('/user/add',(req,res) => {
    res.send('Add a new user')
})
//4、向外导出路由对象
module.exports = router
注册路由模块
// 1、导入 Express
const express = require('express')
// 2、创建 web 服务器
const app = express()

// 1、导入路由模块
const router = require('./router.js')
// 2、注册路由模块
app.use(router)

// 3、启动 web 服务器
app.listen(80, ()=>{
    console.log('express server running at http://127.0.0.1')
})

运行效果如下:

在这里插入图片描述

可以发现路由模块化后也依然可以正常工作。

app.use() 函数的作用

一句话:该函数的作用就是用来注册全局中间件的(后面就会讲到了)。

为路由模块添加前缀

在这里插入图片描述

Express 中间件

什么是中间件

中间件(Middleware),特指业务流程的中间处理环节。

比如:

在这里插入图片描述

Express 中间件的调用流程

在这里插入图片描述

Express 中间件的格式

在这里插入图片描述

next 函数的作用

在这里插入图片描述

Express 中间件的初体验

在这里插入图片描述

代码示例如下:

const express = require('express')

const app = express()

// 定义一个最简单的中间件函数
const mw = function (req, res, next){
    console.log("这是最简单的中间件函数")
    //把流转关系,转交给下一个中间件或者路由
    //(有中间件转交给中间件,没中间件就转交给路由)
    next()
}

app.listen(80, () => {
    console.log('http://localhost')
})

全局生效的中间件

在这里插入图片描述

示例代码如下:

const express = require('express')

const app = express()

// 定义一个最简单的中间件函数
const mw = function (req, res, next){
    console.log("这是最简单的中间件函数")
    //把流转关系,转交给下一个中间件或者路由
    //(有中间件转交给中间件,没中间件就转交给路由)
    next()
}

//将 mw 注册为全局生效的中间件
app.use(mw)

app.get('/',(req,res)=>{
	console.log('Here is Home Page')
    res.send('Home page')
})

app.get('/user',(req,res)=>{
    res.send('User page')
})

app.listen(80, () => {
    console.log('http://localhost')
})

运行效果如下:

在这里插入图片描述

可以看见访问浏览器时是成功打印了:

在这里插入图片描述

因为目前我们只定义了一个中间件,因此在 mw 中间件函数执行结束之后因为没有其他中间件了,于是 next() 函数将流转关系转交给了路由模块,所以先打印 “这是最简单的中间件函数” 再打印 “Here is Home Page”。

定义全局中间件的简化形式

在这里插入图片描述

中间件的作用

在这里插入图片描述

示例代码:

const express = require('express')

const app = express()

// 定义一个最简单的中间件函数
const mw = function (req, res, next){
    //获取请求到达服务器的时间
    const time = Date.now()
    //为 req 对象挂载自定义属性,从而把时间共享给后面的所有路由
    req.startTime = time
    //把流转关系,转交给下一个中间件或者路由
    //(有中间件转交给中间件,没中间件就转交给路由)
    next()
}

//将 mw 注册为全局生效的中间件
app.use(mw)

app.get('/',(req,res)=>{
    res.send('Home page'+req.startTime)
})

app.get('/user',(req,res)=>{
    res.send('User page'+req.startTime)
})

app.listen(80, () => {
    console.log('http://localhost')
})

运行效果:

在这里插入图片描述

定义多个全局中间件

在这里插入图片描述

局部生效的中间件

在这里插入图片描述

定义多个局部中间件

在这里插入图片描述

注意调用顺序是从前往后的,即先执行 mw1 再执行 mw2。

了解中间件使用的5个使用注意事项

在这里插入图片描述

中间件的分类

在这里插入图片描述

应用级别的中间件:

在这里插入图片描述

路由级别的中间件:

在这里插入图片描述

错误级别的中间件:

在这里插入图片描述

注意:错误级别的中间件,必须注册在所有路由之后!

Express 内置的中间件

在这里插入图片描述

express.json() 内置中间件

代码示例:

const express = require('express')
const app = express()

//注意:除了错误级别的中间件,其他的中间件,必须在路由之前进行配置
//通过 express.json() 这个中间件,解析表单中的 JSON 格式的数据
app.use(express.json())

app.post('/user',(req,res)=>{
    // 在服务器中可以使用 req.body 这个属性来接收客户端发送过来的请求体数据
    // 默认情况下,如果不配置解析表单数据的中间件(也就是 express.json()),则 req.body 默认为 undefined
    console.log(req.body)
    res.send('ok')
})

app.listen(80, ()=>{
    console.log('http://localhost')
})

运行效果,我们使用 postman 工具来进行测试:

发送 JSON 类型的请求体数据如下:

在这里插入图片描述

此时控制台中的输出如下:

在这里插入图片描述

可以看见请求体数据被完美解析。

express.urlencoded() 内置中间件

示例代码如下:

const express = require('express')
const app = express()

//注意:除了错误级别的中间件,其他的中间件,必须在路由之前进行配置
//通过 express.urlencoded() 这个中间件,解析表单中的 JSON 格式的数据
//在这个函数内部我们还要传递一个固定的配置对象 extended ,将其设置为 false
//这是固定的写法,只需要记住,不需要问为什么
app.use(express.urlencoded({ extended: false }))

app.post('/book',(req,res)=>{
    // 在服务器中可以使用 req.body 这个属性来接收客户端发送过来的 url-encoded 格式的数据
    // 默认情况下,如果不配置解析 url-encoded 表单数据的中间件,则 req.body 默认为空
    console.log(req.body)
    res.send('ok')
})

app.listen(80, ()=>{
    console.log('http://localhost')
})

发送数据类型为:

在这里插入图片描述

运行效果为:

在这里插入图片描述

可以看见正常解析了数据。

第三方中间件

在这里插入图片描述

自定义中间件

在这里插入图片描述

实现如下:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

使用 Express 写 API 接口

1、创建基本的服务器:

// app.js 主模块
// 导入 express
const express = require('express')

// 创建服务器实例
const app = express()

// 调用 app.listen() 方法,指定端口号并启动 web 服务器
app.listen(80,()=>{
    console.log('Express server is running at http://localhost')
})

2、创建 API 路由模块

// apiRouter.js 路由模块
const express = require('express')

const router = express.Router()

//在这里挂载对于的路由

module.exports = router

然后在 app.js 中导入并注册路由模块:

// app.js 主模块
// 导入 express
const express = require('express')

// 创建服务器实例
const app = express()

//导入路由模块
const router = require('./apiRouter')
//把路由模块注册到 app 上
app.use('/api', router)

// 调用 app.listen() 方法,指定端口号并启动 web 服务器
app.listen(80,()=>{
    console.log('Express server is running at http://localhost')
})

3、编写 Get 接口

// apiRouter.js 路由模块
const express = require('express')

const router = express.Router()

//在这里挂载对应的路由
router.get('/get', (req,res)=>{
    //通过 req.query 获取客户端通过查询字符串,发送到服务器的数据
    const query = req.query
    //调用 res.send() 方法,向客户端响应处理的结果
    res.send({
        stats: 0,//0 表示处理成功,1 表示处理失败
        msg: 'Get 请求成功', // 状态描述
        data: query //需要响应给客户端的数据
    })
})

module.exports = router

运行结果如下:

在这里插入图片描述

4、编写 Post 接口

// apiRouter.js 路由模块
const express = require('express')

const router = express.Router()

//在这里挂载对应的路由
router.get('/get', (req,res)=>{
    //通过 req.query 获取客户端通过查询字符串,发送到服务器的数据
    const query = req.query
    //调用 res.send() 方法,向客户端响应处理的结果
    res.send({
        stats: 0,//0 表示处理成功,1 表示处理失败
        msg: 'Get 请求成功', // 状态描述
        data: query //需要响应给客户端的数据
    })
})

router.post('/post', (req,res)=>{
    //通过 req.body 获取客户端发送到服务器的请求体数据
    const body = req.body
    //调用 res.send() 方法,向客户端响应处理的结果
    res.send({
        stats: 0,//0 表示处理成功,1 表示处理失败
        msg: 'Post 请求成功', // 状态描述
        data: body //需要响应给客户端的数据
    })
})

module.exports = router

要解析表单数据别忘了在导入路由之前先添加配置解析表单数据的中间件:

// app.js 主模块
// 导入 express
const express = require('express')

// 创建服务器实例
const app = express()

//配置解析表单数据的中间件
app.use(express.urlencoded({ extended: false}))
app.use(express.json())

//导入路由模块
const router = require('./apiRouter')
//把路由模块注册到 app 上
app.use('/api', router)

// 调用 app.listen() 方法,指定端口号并启动 web 服务器
app.listen(80,()=>{
    console.log('Express server is running at http://localhost')
})

运行效果如下:

在这里插入图片描述

接口的跨域问题

在这里插入图片描述

接口跨域问题是指在Web开发中,由于浏览器的同源策略(Same-Origin Policy),导致在一个域下的网页无法直接访问另一个域下的资源。"跨域"指的是在浏览器中,当一个页面的脚本请求访问另一个域下的资源时,如果这个资源的域名、协议或端口与当前页面所在的域不一致,就会引发跨域问题。

跨域问题会影响到包括Ajax请求、Web字体加载、嵌入式框架(如iframe)加载等场景。具体来说,如果你在一个网页中使用Ajax请求另一个域下的数据,浏览器会阻止这个请求,因为涉及到跨域。

解决接口跨域问题的方法有很多,包括使用代理服务器、JSONP、CORS(跨域资源共享)等。CORS是一种比较常用的解决方案,它通过在服务器端设置一些响应头,来告诉浏览器允许跨域请求。JSONP则是一种利用

实际开发中,我们推荐使用 CORS 的方法来解决跨域问题。

使用 CORS 中间件解决跨域问题

在这里插入图片描述

第一步:安装

在这里插入图片描述

第二步和第三步:在路由之前先配置并注册 cors 中间件到 app.js 上

// app.js 主模块
// 导入 express
const express = require('express')

// 创建服务器实例
const app = express()

//配置解析表单数据的中间件
app.use(express.urlencoded({ extended: false}))
app.use(express.json())

//在路由之前先配置 cors 中间件解决跨域问题
const cors = require('cors')
//注册 cors 中间件
app.use(cors())

//导入路由模块
const router = require('./apiRouter')
//把路由模块注册到 app 上
app.use('/api', router)

// 调用 app.listen() 方法,指定端口号并启动 web 服务器
app.listen(80,()=>{
    console.log('Express server is running at http://localhost')
})

这样就可以解决跨域问题啦。

什么是 CORS

在这里插入图片描述

CORS 的注意事项

在这里插入图片描述

CORS 响应头部 -Access-Control-Allow-Origin

在这里插入图片描述

在这里插入图片描述

CORS 响应头部 -Access-Control-Allow-Headers

在这里插入图片描述

CORS 响应头部 -Access-Control-Allow-Methods

在这里插入图片描述

CORS 请求的分类

在这里插入图片描述

简单请求

在这里插入图片描述

预检请求

在这里插入图片描述

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

简单请求和预检请求之间的区别

在这里插入图片描述

数据库与身份认证

在这里插入图片描述

注意这一章节的学习中省略了 MySQL 相关的基础内容,如果不会的话建议先去系统学一下 MySQL 捏。

这里只讲 Express 中如何操作 MySQL 数据库嗷。

测试的表数据如下:

在这里插入图片描述

在 Express 中操作 MySQL

在项目中操作 MySQL 数据库的步骤:

在这里插入图片描述

安装 mysql 模块:

在这里插入图片描述

配置 mysql 模块:

在这里插入图片描述

示例代码如下:

//mysql-cfg.js 数据库模块
//1、导入 mysql 模块
const mysql = require('mysql')

//2、建议与 mysql 数据库的连接关系
const db = mysql.createPool({
    host: '127.0.0.1', //数据库的 ip 地址
    user: 'root', //登录数据库的账号
    password: '123456', //登录数据库的密码
    database: 'node' //指定要操作哪一个数据库
})

测试一下 mysql 模块是否能正常工作:

//mysql-cfg.js 数据库模块
//1、导入 mysql 模块
const mysql = require('mysql')

//2、建议与 mysql 数据库的连接关系
const db = mysql.createPool({
    host: '127.0.0.1', //数据库的 ip 地址
    user: 'root', //登录数据库的账号
    password: '123456', //登录数据库的密码
    database: 'node' //指定要操作哪一个数据库
})

// 测试 mysql 模块能否正常工作
// select 1 这条语句没有任何意义,只是用来检查 mysql 能否正常工作
db.query('select 1',(err, results)=>{
    // mysql 模块工作期间报错了
    if(err){
        return console.log(err.message)
    }
    //否则就是能够正常的执行 SQL 语句
    console.log(results)
})

测试运行结果如下:

在这里插入图片描述

可以看见我们的 mysql 模块是没有问题的。

使用 mysql 模块操作 MySQL 数据库

查询数据

在这里插入图片描述

示例代码如下:

//mysql-cfg.js 数据库模块
//1、导入 mysql 模块
const mysql = require('mysql')

//2、建议与 mysql 数据库的连接关系
const db = mysql.createPool({
    host: '127.0.0.1', //数据库的 ip 地址
    user: 'root', //登录数据库的账号
    password: '123456', //登录数据库的密码
    database: 'node' //指定要操作哪一个数据库
})

// 查询 users 表中所有的数据
const str = "select * from user"
db.query(str,(err, results)=>{
    // mysql 模块工作期间报错了
    if(err){
        return console.log(err.message)
    }
    //否则就是能够正常的执行 SQL 语句
    console.log(results)
})

运行结果如下:

在这里插入图片描述

注意:如果执行的是 select 查询语句,则执行的结果是数组。

插入数据

在这里插入图片描述

示例代码:

//mysql-cfg.js 数据库模块
//1、导入 mysql 模块
const mysql = require('mysql')

//2、建议与 mysql 数据库的连接关系
const db = mysql.createPool({
    host: '127.0.0.1', //数据库的 ip 地址
    user: 'root', //登录数据库的账号
    password: '123456', //登录数据库的密码
    database: 'node' //指定要操作哪一个数据库
})

// 向 user 表中新增一条数据,其中username的值为 Spider,password 的值为123
const user = {username:'Spider', password:'123'}
//定义待执行的 SQL 语句
const sqlStr = 'insert into user (username, password) values (?, ?)'
//执行 SQL 语句
db.query(sqlStr,[user.username,user.password],(err,results)=>{
    if(err) return console.log(err.message)
    // 注意:如果执行的是 insert into 插入语句,则 results 是一个对象
    // 可以通过 affectedRows 属性,来判断是否插入数据成功
    if(results.affectedRows === 1) console.log('插入数据成功')
})

插入数据的便捷方式

在这里插入图片描述

示例代码:

//mysql-cfg.js 数据库模块
//1、导入 mysql 模块
const mysql = require('mysql')

//2、建议与 mysql 数据库的连接关系
const db = mysql.createPool({
    host: '127.0.0.1', //数据库的 ip 地址
    user: 'root', //登录数据库的账号
    password: '123456', //登录数据库的密码
    database: 'node' //指定要操作哪一个数据库
})

// 向 user 表中新增一条数据,其中username的值为 Spider,password 的值为123
const user = {username:'Spider', password:'123'}
//定义待执行的 SQL 语句
//insert into 表名 set ?
const sqlStr = 'insert into user set ?'
//执行 SQL 语句
// 参数也不需要用数组形式了,直接将原对象进行插入即可(类似于一个 JavaBean)
db.query(sqlStr,user,(err,results)=>{
    if(err) return console.log(err.message)
    // 注意:如果执行的是 insert into 插入语句,则 results 是一个对象
    // 可以通过 affectedRows 属性,来判断是否插入数据成功
    if(results.affectedRows === 1) console.log('插入数据成功')
})


运行结果如下:

在这里插入图片描述

数据库中也是正常的新增了数据:

在这里插入图片描述

更新数据

在这里插入图片描述

示例代码:

//mysql-cfg.js 数据库模块
//1、导入 mysql 模块
const mysql = require('mysql')

//2、建议与 mysql 数据库的连接关系
const db = mysql.createPool({
    host: '127.0.0.1', //数据库的 ip 地址
    user: 'root', //登录数据库的账号
    password: '123456', //登录数据库的密码
    database: 'node' //指定要操作哪一个数据库
})

// 向 user 表中修改一条数据
const user = { id: 3, username:'阿斯顿', password:'123' }
//定义待执行的 SQL 语句
const sqlStr = 'update user set username=?,password=? where id=?'
//执行 SQL 语句
db.query(sqlStr,[user.username,user.password,user.id],(err,results)=>{
    if(err) return console.log(err.message)
    // 注意:如果执行的是 update 更新语句,则 results 是一个对象
    // 可以通过 affectedRows 属性,来判断是否更新数据成功
    if(results.affectedRows === 1) console.log('更新数据成功')
})


运行结果如下:

在这里插入图片描述

更新数据的便捷方式

在这里插入图片描述

删除数据

在这里插入图片描述

标记删除

在这里插入图片描述

前后端中的身份认证

Web 开发模式

目前主流的 Web 开发模式有两种,分别是:

1、基于服务端渲染的传统 Web 开发模式

2、基于前后端分离的新型 Web 开发模式

基于服务端渲染的传统 Web 开发模式

在这里插入图片描述
在这里插入图片描述

基于前后端分离的新型 Web 开发模式

在这里插入图片描述

在这里插入图片描述

如何选择 Web 开发模式

在这里插入图片描述

身份认证

什么是身份认证?
在这里插入图片描述

为什么需要身份认证

在这里插入图片描述

不同开发模式下的身份认证

在这里插入图片描述

HTTP 协议的无状态性

在这里插入图片描述

如何突破 HTTP 无状态的限制

在这里插入图片描述

什么是 Cookie

在这里插入图片描述

Cookie 在身份认证中的作用

在这里插入图片描述

Cookie 不具有安全性

在这里插入图片描述

注意:千万不要使用 Cookie 存储重要且隐私的数据!比如用户的身份信息、密码等。

提高身份认证的安全性

在这里插入图片描述

Session 的工作原理

在这里插入图片描述

在 Express 中使用 Session 认证

配置 Session

只需要下面几步就可以使用 Session 认证了嗷:

在这里插入图片描述
在这里插入图片描述

配置对象中的 secret 属性是一串字符串,用来加密用的。

接下来我们完成一下这些事情:

安装 express-session 中间件:

在这里插入图片描述

开始配置 express-session 的全局中间件:

// app.js 主模块
// 导入 express
const express = require('express')

// 创建服务器实例
const app = express()

// 引入session
const session = require('express-session')
// 注册 session
app.use(session({
    secret: 'hahaha',
    resave: false,
    saveUninitialized: true
}))

//配置解析表单数据的中间件
app.use(express.urlencoded({ extended: false}))
app.use(express.json())

//在路由之前先配置 cors 中间件解决跨域问题
const cors = require('cors')
//注册 cors 中间件
app.use(cors())

//导入路由模块
const router = require('./apiRouter')
//把路由模块注册到 app 上
app.use('/api', router)

// 调用 app.listen() 方法,指定端口号并启动 web 服务器
app.listen(80,()=>{
    console.log('Express server is running at http://localhost')
})
向 Session 中存数据

在这里插入图片描述

从 Session 中取数据

在这里插入图片描述

清空 Session

在这里插入图片描述

注意:只是清空了当前客户端的 Session ,这并不会影响到其他客户端的 Session。

因为之前说过 Session 的工作原理,每个 Session 都会对应一个客户端浏览器所自动存收的一个 Cookie,因此相当于各个客户端之间是隔离连接的,互不影响,至于底层是怎么实现的应该是在这个 express-session 第三方包中自动实现的,我们只要懂得怎么使用即可。

了解 Session 认证的局限性

在这里插入图片描述

什么是 JWT

JWT(英文全称:JSON Web Token)是目前最流行的跨域认证解决方案。

JWT 的工作原理

在这里插入图片描述

JWT 的组成部分

在这里插入图片描述

JWT 的三个部分各自代表的含义

在这里插入图片描述

JWT 的使用方式

在这里插入图片描述

注意:千万别忘记了在 token 字符串前加 Bearer 这个字符串!然后后面还要跟一个空格才能再跟 token 字符串!!!

比如我们在 postman 中要带 token 的话,那么形式应该是下面这样:

在这里插入图片描述

在 Express 中使用 JWT

主要有下面几个步骤:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

上图中的第三个参数配置对象里,我们配置了该 Token 的过期时间为 30s,如果要设置成分钟则后缀用 m ,小时的话设置为 h 即可。

在这里插入图片描述

注意:只要配置成功了 express-jwt 这个中间件,就可以把解析出来的用户信息,挂载到 req.user 属性上。

换句话说就是,req 本身是没有 user 属性的,但是只要配置成功了 express-jwt 这个中间件后,req 就有一个 user 属性了,该属性是由该中间件创建的。

而这个 user 对象中包含多少信息是由我们自己决定的,也就是在登录成功之后我们进行加密的用户信息对象信息有多少那么 user 对象中就有多少信息。

比如我们上面的示例中将 username 进行了加密,那么被创建的 user 对象就会只有一个 username 属性。

如果我们的访问请求携带了 token 进行 API 访问的话,其返回值会有下面两个额外的属性:

在这里插入图片描述

iat 和 exp ,不过不用管,这是这个 JWT 第三方工具包用来控制过期时间用的两个属性。

捕获解析 JWT 失败后产生的错误

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

二.PVE创建 Ubuntu CT

二&#xff0e;PVE创建 Ubuntu CT 浏览器地址栏输入访问pve系统的网址&#xff0c;利用web端进行管理。注意进入pve系统时默认显示的有访问地址。本步骤的web访问地址为&#xff1a;https://192.168.1.102:8006。 出现该页面&#xff0c;选择继续前往。 进入管理页面后&…

图文成片剪辑软件,分享3个专业的工具!

在数字化时代&#xff0c;图文成片剪辑软件成为了我们创作与表达的重要工具。无论是想要制作一段引人入胜的短视频&#xff0c;还是打造一幅精美的图文海报&#xff0c;这些软件都能助你一臂之力。那么&#xff0c;图文成片剪辑软件的方法有哪些&#xff1f;又有哪些值得一试的…

衡量代理IP的因素

当你随便点开百度搜索IP代理&#xff0c;然后你就会看到&#xff0c;五花八门的IP代理商出现在视线中。再点进去链接&#xff0c;我们会发现&#xff0c;大多数IP代理商提供的基础IP服务都大差不差&#xff0c;东家这样说&#xff0c;西家又那样说&#xff0c;尽管我们看的头昏…

三步在 vite 中配置 tailwindcss

前言 tailwindcss 是一个原子化的 css 工具&#xff0c;可以让你免于写 css&#xff0c;只写 html 即可原理&#xff1a;利用你写的 html 的 class 名称来生成 css 样式&#xff0c;理解为一个 postcss 插件或 loader 第一步&#xff1a;安装 tailwindcss npm i -D tailwind…

JVM运行时内存:本地方法接口与本地方法栈

文章目录 1. 什么是本地方法&#xff1f;2. 为什么要使用Native Method&#xff1f;3. 本地方法现状 运行时内存整体结构如下图所示: 1. 什么是本地方法&#xff1f; 简单地讲&#xff0c;一个Native Method就是一个Java调用非 Java 代码的接口。一个Native Method是这样一个 …

GBDT调参--贝叶斯调参

随机抽特征和随机抽样本 n_estimators 是控制森林中树木的数量&#xff0c;即基评估器的数量。这个参数对随机森林模型的精确性影响是单调的&#xff0c;n_estimators越 大&#xff0c;模型的效果往往越好。但是相应的&#xff0c;任何模型都有决策边 n_estimators达到一定的程…

【资源汇总】GIS/RS相关软件包+数据分享(直接获取附链接)

01软件类 ArcGIS 10.2 链接&#xff1a;https://pan.baidu.com/s/1euHa3eTiaTjiOu-zxsi9eA?pwdnjov ArcGIS Pro 2.8.6 链接&#xff1a;https://pan.baidu.com/s/1Y3AQshCGL7tA1zdUc7s9PQ?pwdlkic ENVI 5.3 链接&#xff1a;https://pan.baidu.com/s/14k4IVlYIheNOr2to…

520告白好物有哪些?收下这份清单不迷茫!

在这个充满爱意的日子里&#xff0c;你是否正在为如何向心仪的人表达深情而犯愁&#xff1f;别担心&#xff0c;我们为你精心准备了一份520告白好物清单都是一些实用的礼品&#xff0c;为你提供多样化的选择&#xff0c;助你轻松传达爱意&#xff0c;让告白不再迷茫。快来看看吧…

网页设计web

效果图代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><style>* …

opencv4.8.0 GPU版本各平台编译

一、opencv4.8.0 ubuntu22.04上编译&#xff1a; 用cmake进行编译,需要配置三次。选中world选项&#xff0c;输入opencv_contrib_module路径。 ubuntu22.04上编译&#xff1a; cmake \ -D CMAKE_BUILD_TYPERELEASE \ -D CMAKE_INSTALL_PREFIX/usr/local \ -D BUILD_opencv_p…

HR人才测评:督导能力与岗位胜任力测评

督导能力指的是什么&#xff1f; 督导能力指的是为了实现某一种目标&#xff0c;不管是客户的利益还是组织的利益&#xff0c;在必要的时候引导他人的行为。对于企业而言&#xff0c;有督导能力的人可以指引企业更好的前进&#xff0c;他们代表的是标准&#xff0c;代表的是榜样…

策略模式详解

策略模式 1 概述 先看下面的图片&#xff0c;我们去旅游选择出行模式有很多种&#xff0c;可以骑自行车、可以坐汽车、可以坐火车、可以坐飞机。 作为一个程序猿&#xff0c;开发需要选择一款开发工具&#xff0c;当然可以进行代码开发的工具有很多&#xff0c;可以选择Idea进…

sqlserver正确配置

一、启动sql server 服务&#xff0c;右键–>启动 二、设置网络协议 三、启动sa用户 1.使用windows用户验证登录Studio工具 2.选择安全性–>登录名–>sa, 右键选择属性 3.设置服务器身份验证模式 4.导入数据库文件

在面对各种问题时,我们应该如何进行数据分析

python数据分析汇总 前言一、对比分析概念特征类型案例Matplotlib的颜色字母对照表解决遇到未知函数 二、相关性分析概念类型案例一案例二 三、时间序列分析概念类型案例 四、回归分析概念类型案例一案例二案例三 五、决策树概念计算过程案例 六、主成分分析概念计算过程案例 七…

【会议征稿,ACM出版】第四届人工智能,大数据与算法国际学术会议 (CAIBDA 2024, 7/5-7)

由河南省科学院、河南大学主办&#xff0c;河南省科学院智慧创制研究所、河南大学学术发展部、河南大学人工智能学院承办的第四届人工智能&#xff0c;大数据与算法国际学术会议 (CAIBDA 2024)将于2024年7月5-7日于中国郑州隆重举行。CAIBDA 2024致力于为人工智能&#xff0c;大…

数据库设计大题详解

大题一&#xff1a;画E-R图&#xff08;概念结构设计&#xff09; 实体就是具体的物品&#xff0c;关系就是实体之间的关系&#xff0c;属性就是特征&#xff0c;内涵的意思 简单的小栗子&#xff1a; 1对1&#xff0c;1对n&#xff0c;n对m&#xff0c;自己考虑两者存在这个关…

ubuntu虚拟机的 网卡不见了?

通过 ifconfig 命令查找不到自己的虚拟机上网网卡了,虚拟机的上网网卡名字是ens33 发现只有一个本地回环地址 执行如下两条指令可恢复网卡 sudo dhclient ens33#获取ip sudo ifconfig ens33#查看ip 再次通过ifconfig查看网卡信息

HP5V80、HP5V105、HP3V28电比例驱动柱塞泵放大器

HP5V80、HP5V105、HP3V28、HP3V45、HP3V60、HP3V80、HP3V125、HP3V140带电比例控制泵放大器&#xff0c;变排量泵的排量可通过由BEUEC比例放大器输出到比例电磁阀电流变化而进行调整&#xff0c;控制电流范围为300mA至800mA(24VDC)或600mA至1600mA(12VDC)。主要适合应用于工程机…

植物大战僵尸杂交版(含下载方式)

最近时间&#xff0c;一款很火的植物大战僵尸杂交版火爆出圈&#xff0c;在玩家之间疯狂扩散。各种奇特的杂交组合让游戏变得更加有趣。 游戏介绍 植物大战僵尸杂交版是一款将《植物大战僵尸》和植物杂交概念结合在一起的独特塔防策略游戏。它将《植物大战僵尸》中的植物与进行…

沉钒废水回收钒

沉钒废水处理与钒回收的重要性 沉钒废水是含钒元素的特殊废水&#xff0c;钒在工业生产中广泛应用&#xff0c;但其排放造成资源浪费与环境威胁。为实现钒的有效回收&#xff0c;研究和实践了多种处理技术。 沉钒废水处理技术 1. 化学沉淀法&#xff1a;添加沉淀剂&#xff…