Node简介

Node.js

一、node.js

node.js官网

node.js是一个基于Javascript这门语言开发出来的技术,本文我就来为大家介绍一下Node.js学习的一些基础内容。如有错误的地方欢迎大家指出错误之处。在我们了解这些基础之后,可以使用node实现一些数据库连接操作,自己写一些前后端小项目。

node运行

在我们安装node并且编写一个js文件之后,我们便可以开始运行我们的node项目了:

node 文件名.js

二、系统模块

2.1 系统模块

Node运行环境提供的API. 因为这些API都是以模块化的方式进行开发的, 所以我们又称Node运行环境提供的API为系统模块

2.2 fs文件系统模块

2.2.1读取、写入文件操作
// 在我们使用node的文件系统模块之前我们需要使用require来导入该模块
const fs = require("fs");

// 读取文件模块

// 同步读取:调用fs.requireFileSync(参数1,参数2) 
// 		参数1:读取文件的路径
// 	 	参数2:读取文件时候所按照的编码格式,一般默认指定utf8
//该方法不接受回调函数,函数直接返回结果
var data = fs.readFileSync('sample.txt', 'utf-8');
console.log(data);

// 异步读取:调用fs.readFile(参数1[,参数2],参数3)方法读取文件
/*
    参数1:读取文件的路径
    参数2:读取文件时候所按照的编码格式,一般默认指定utf8
    参数3:回调函数,拿到读取失败和成功的结果 err dataStr
*/ 
fs.readFile('../files/1s.txt','utf8',(err,dataStr)=>{
    // 打印失败的结果
    // 如果读取成功返回null
    // 读取失败返回一个错误对象,dataStr 的值为undefined
    console.log(err);
    console.log('=====');
    // 打印成功的结果
    console.log(dataStr);

    if(err){
        return console.warn('读取文件失败!'+ err.message);
    }
    console.log(dataStr);
})

// 写入文件模块
// 调用writeFile(参数1,参数2[,参数3],参数4)函数为文件写入内容
// 参数1:写入文件存放的路径(如果写入的文件不存在,则系统会自动地生成相对应的文件)
// 参数2:表示写入的内容
// 参数3: 回调函数
fs.writeFile('../files/1.txt','这是一段写入的内容',(err)=>{
    // 如果文件写入与成功,则err为null
    // 如果写入失败,则err等于一个错误对象
    console.log(err);
})

2.3 http系统模块

我们可以使用node内置模块的http模块,来创建一个web服务器,可以进行一些简单的前后端交互操作。使用http模块的基本的步骤如下:

// 创建基本的web服务器
// 1.导入http模块
const http = require('http');
// 2.创建web服务器实例
const serve = http.createServer()

//3.绑定处request事件
// serve.on('request',处理函数(req,res))
/*
    当客服端请求服务端时,就会调用serve.on()函数为服务器的request事件绑定处理函数
    req:是请求的对象,包含了与客户端相关的数据和属性:如:  
        req.url :客户端请求的URL地址,但是只会获取地址后面的后缀,如:http://127.0.0.1/user,这是req.url只会获取到 /user
        req.method :客户端的method请求类型

    res :响应对象,包含与服务端相关的数据和属性,如:
        res.end()方法的作用:向客户端发送指定的内容,并且结束这次请求的处理过程
        res.setHeader() 设置响应头:(设置该响应头是为了防止中文乱码)
            'Content-type':'text/html;charset=utf-8

*/ 
serve.on('request',(req,res)=>{
    console.log('开始请求web服务');
})

// 4.启动服务器
// serve.listen('端口',callback)
// 我们可以自己设置响应的端口号,如:8080、8088等等。当我们使用80作为我们服务器的端口号的时候,我们在访问的时候,不需要加端口号,浏览器会默认的认为是80端口访问
serve.listen(80,()=>{
    console.log('http://l27.0.0.1');
})
一个简单的案例

响应不同的请求地址

const http = require('http');
const server = http.createServer();
server.on('request',(req,res)=>{
    let content = '404 NOt Found';
    if(req.url === '/' || req.url === '/index.html'){
        content = '<h1>index.html</h1>'
    }
    if(req.url === '/about.html'){
        content=  '<h1>About.html</h1>'
    }
    res.setHeader('Content-type','text/html; utf-8;')
    res.end(content);
})
server.listen(8080,()=>{
    console.log('Your server at http://127.0.0.1:8080');
})

2.3 path路径模块

path 模块是Node.js官方提供的、用来处理路径的模块。它提供了一系列的方法和属性,用来满足用户对路径的处理需求。

在我们平时遇到路径拼接的操作时,都会选择使用字符串拼接的方法,但是使用这种方法的弊端有很多,如:有时候会由于我们的一些失误,导致路径出现错误的情况,而且在如果我们要将文件移植的时候,会导致移植性差。这个时候我们就可以使用path模块,来对路径做一些修改和拼接。

今后凡是涉及到路径拼接的操作,都要使用path.join()方法进行处理。不要直接使用+ 进行字符串拼接。

// path.join([...path])方法,用来将多个路径片段拼接成一个完整的路径字符串
/*
	paths<string>路径片段的序列
	返回值<string>
*/
// path.basename(path[,ext])方法,用来从路径字符串中,将文件解析出来
/* 	path <string> 必选参数,表示一个路径的字符串
	ext <string>  可选参数,表示文件扩展名
	返回:<string> 表示路径中的最后一部分
*/	
// path.extname(path)的语法格式
/*
	path <string> 必选参数,表示一个路径的字符串
	返回:<string> 返回得到的扩展名字符串
*/


// 引入path模块,在之后涉及到路径拼接的时候,记得使用path.join的方法,不会出现什么问题

// 拼接路径
// path.join([..arg])
const path = require('path');


// 在拼接路径的时候,只有../能回退目录
const url = path.join('/a','/b','../');
// __dirname会返回当前文件所在的目录的路径
const url2= path.join(__dirname)
console.log(url,url2);

const fpath = '/a/v/c/index.html';
console.log(path.extname(fpath)); //html

const fapth = __dirname + '/index.html';
const fullName = path.basename(fapth,'.html');
console.log(fullName); // index

三、require

/*
    require:用来导入相关的模块
    1.内置模块 2.用户自定义模块 3.第三方模块 (也可以叫做 包 ,是依赖于内置模块封装出来的)
    其中只有用户自定义模块引入时,需要添加路径
    在使用require引入模块时,会自动执行模块中的代码
    存在模块作用域
    在一个模块中的,如果需要导出数据的话,需使用module.exports方法,且导出的对象以最后的module.export指向的对象为准
    在模块里面,exports和module.exports所指向的对象相同 export === module.exports => true
    切记:使用require()导入模块时,得到的永远是module.exports指向的对象,并非exports
    避免在同一个模块中同时使用exports 和 module.exports
    我们在使用require导入时,如果不添加文件的后缀名,则系统会自动的按照 js json node 的顺序逐层的向上寻找去寻找,如果都没有找到,则会报错 
*/

const m1 = require('./test')

console.log(m1);


// test.js
console.log(module);
module.exports = {
    name: '小明',
    age: 20
}
module.exports = {
    name: 20
}
module.exports.wife = 30;

四、Express框架

1.1nodemon

// nodemon: 在编写Node.js项目时,如果修改项目代码,就需要频繁的重启,很繁琐,使用nodemon就可以很好的解决这个问题,它会自动的重启项目,方便我们开发和调试

// 安装nodemon : npm i -g nodemon

//执行:  nodemon 执行文件路径

2.1 Express

Express 是一个基于 Node平台的Web应用开发框架,它提供了一系列的强大特性,帮助你创建各种Web应用。

express安装: npm i express

2.2 Express 框架特性

  • 提供了简洁的路由定义方式

  • 对获取 http 请求参数进行了简化处理

  • 模板引擎支持程度高,方便渲染动态HTML页面

  • 拥有中间件机制有效控制 HTTP 请求

  • 拥有大量第三方中间件对功能进行扩展

请添加图片描述

请添加图片描述

2.3 express初体验

// 导入express
const express = require('express');
// 创建web服务器
const app = express();
// 编写post请求方法
app.post('/post',(req,res)=>{
    res.send("POST")
})
// 编写get请求方法
app.get('/', (req, res) => {
    res.send("GET");
})
// 启动服务器
app.listen(80,()=>{
    console.log('http://127.0.0.1');
})

3.中间件

3.1 是什么中间件

中间件:业务处理流程中的处理函数

中间件是一堆方法,可以接收客户端发来的请求、可以对请求作出响应,也可以将请求继续交给下一个中间件进行处理

请添加图片描述

/*   
中间件:业务处理流程中的处理函数

    全局生效的中间件:任何一个客户端请求,到达服务端都会触发的中间件。叫做全局中间件
    通过调用app.use(中间函数),即可定义一个全局生效的中间件

    局部生效的中间件:不使用app.use()定义的中间件,都叫做局部中间件

    中间件作用:多个中间件之间共享的是同一份req和res.所以我们可以在上游的中间件中,统一
        为req和res对象添加自定义属性或方法,供下游的中间件或路由进行使用

    定义多个全局中间件:可以使用app.use()连续定义多个中间件,系统会按照定义的顺序
        进行执行

    中间件使用注意事项:
        1.一定要将中间件放置在路由之前
        2.客户端发送的请求,可以连续调用多个中间件
        3.不要忘记在中间件函数里面写next()函数
        4.为了防止代码逻辑混乱,调用next()函数后不要写额外的代码
        5.连续调用多个中间件,多个中间件之间,共享req 和 res对象

    中间件的分类:
        1.应用级别:绑定到app实例上的中间件,如app.use()、app.get()
        2.路由级别:绑定到路由上的中间件
        3.错误级别:专门用来捕获整个项目中发生的异常错误,从而防止项目异常崩溃的问题
                app.use(function(err,req,res,next){
                    console.log('发生错误' + err.message);
                    res.send('Error! + err.message)
                })
                特殊:必须注册在所有路由之后
        4.Express内置:express.static :没有兼容性
                      express.json 解析JSON格式(有兼容性,仅在4.16.0+版本中使用)
                      express.urlencoded 解析URL-encoded格式的请求数据(有兼容性,仅在4.16.0+版本中使用)
        5.第三方    
 */
        
        
// 定义一个简单的中间件函数
const express = require('express');

const app = express();
const mw = function(req,res,next){
    const time = Date.now();
    req.startTime = time;
    console.log('一个简单的中间件函数');
    next()
}
const mw2 = function(req,res,next){
    const time = Date.now();
    req.startTime = time;
    console.log('一个简单的中间件函数');
    next()
}
//全局中间件
// app.use(mw)

// 局部生效的中间件(同时使用多个局部中间件,或者使用数组将中间件包起来,然后调用)
app.get('/',mw,mw2,(req,res)=>{

    res.send('Index.html' + (Date.now() - req.startTime))
})

app.post('/user',(req,res)=>{
    res.send('没中间件')
})

app.get('/error',(req,res)=>{
    throw new Error('服务器内部发生错误!!')
})

// 错误级别中间件,捕获整个项目的异常错误,从而防止程序崩溃
app.use(function(err,req,res,next){
    res.send('服务器错误' + err.message)
})

app.listen(80,()=>{
    console.log('https://127.0.0.1');
})
        
3.2 中间件的应用

1.路由保护:
客户端在访问需要登录的页面时,可以先使用中间件判断用户登录状态,用户如果未登录,则拦截请求,直接响应,禁止用户进入需要登录的页面

// 引入 express 框架
const express = require('express')

// 创建Web服务器
const app = express();

// 为客户端访问 /user 请求时候的中间件
app.use('/user', (req, res, next) => {
    // 用户没有登录
    let isLogin = false;
    // 如果用户登录
    if (isLogin) {
        console.log("用户已经登录")
        // 让请求继续向下执行
        next();
    } else {
        console.log("用户未登录")
        // 如果用户没有登录,直接对客户端作出响应
        res.send('您还没有登录,无法访问当前页面');
    }
})


app.get('/user', (req, res) => {
    res.send('您已登录 可以访问当前页面')
})

app.get("/admin",(req,res)=>{
	res.send("不受中间件约束")
})

// 监听端口
app.listen(3000);
console.log('网站服务器启动成功');

请添加图片描述

请添加图片描述

请添加图片描述

请添加图片描述

2.网站维护公告
在所有路由最上面定义接收所有请求的中间件,直接为客户端做出响应,网站正在维护中。

// 引入 express 框架
const express = require('express')

// 创建Web服务器
const app = express();
// 此处不设置next()函数,阻止用户访问网站
app.use((req, res, next) => {
    res.send('当前网站正在维护...');
})

// 将不会被访问
app.get('/user', (req, res) => {
    res.send('您已登录 可以访问当前页面')
})

// 监听端口
app.listen(80,()=>{
	console.log('http://127.0.0.1')
});


3.自定义404页面

// 引入 express 框架
const express = require('express')

// 创建Web服务器
const app = express();

app.use((req, res, next) => {
    // 为客户端响应404状态码以及提示信息
    res.status(404).send('当前访问的页面是不存在的');
})
// 监听端口
app.listen(80,()=>{
	console.log("http://127.0.0.1")
});

请添加图片描述

请添加图片描述

重点:
// 使用res.send()方法向客户端发送数据
// 使用req.query属性,可以访问到客户端通过查询字符串的形式,发送到服务器的参数
// 使用req.params对象,可以访问到URL中,通过:匹配到的动态参数
/* 使用req的data事件,来获取客户端发送到服务器的数据:如果客户端返回的数据比较多的话,客户端会将数据分割成好几部分,则data事件会触发多次,
        没触发一次就会获取一些数据,我们需要对这些数据进行拼接
    req的end事件:当客户端所有的数据发送完毕之后,会触发end事件

4.express路由

4.1路由
// 路由:就是一种映射关系
/*
    路由的组成:三部分 请求类型、请求地址、处理函数
    app.METHOD(PATH,HANDLER)

    路由匹配过程:每当一个请求到达服务器之后,需要先经过路由的匹配,只有匹配成功之后,才调用对应的处理函数
        注意:按照定义的先后顺序进行匹配;请求类型和请求的URL同时匹配成功,才会调用对应的处理函数

    使用:
    1.简单的使用:(缺点随着路由的增多,代码量会增加)
        引入调用:const express = require(express)
                const app = express();
        挂载路由:
                app.get(地址,(req,res)=>{})
        启动服务器:
                app.listen(启动端口,()=>{})
    
    2.模块化路由(推荐使用)
        创建路由模块对应的.js文件

        调用express.Router()函数创建路由对象

        想路由对象上挂载具体的路由

        使用module.exports向外共享路由

        使用app.use()函数注册路由模块
*/

// express路由.js
const express = require('express');  
const router = express.Router();
router.get('/',(req,res)=>{
    res.send('GET');
})
router.post('/',(req,res)=>{
    res.send('POST')
})
module.exports = router

// router.js
const express = require('express');
const app = express();
const router = require('./express路由')
// app.use()是用来注册全局中间件的
app.use(router)

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


4.2 GET请求参数的获取

Express 框架中使用 req.query 即可 获取GET参数 ,框架内部会将GET参数转换为对象并返回。

img

// 引入 express 框架
const express = require('express');
// 创建Web服务器
const app = express();

app.get('/index', (req, res) => {
    // req.query 获取请求参数
    res.send(req.query)
})

// 监听端口
app.listen(80,()=>{
    console.log('http://127.0.0.1')
});


请添加图片描述

4.3POST参数
Express 中接收 POST请求参数

在服务器,可以使用req.body这个属性来获取客户端发送过来的请求体数据,默认情况下,如果不配置解析表单的中间件,则req.body 默认等于 undefined

方法一:需要借助第三方包 body-parser

img

安装body-parser: npm i body-parser

body-parser文档地址:http://www.expressjs.com.cn/en/resources/middleware/body-parser.html

// 引入 express 框架
const express = require('express');
// 创建Web服务器
const app = express();
const bodyParser = require("body-parser")
//配置body-parser
//只要加入这个配置,则在req请求对象上多出来一个属性:body;
//也就是说你就可以直接通过req.body来获取表单POST请求体数据了;
// 拦截所有请求
// extended: false  方法内部使用 querystring 模块处理请求参数的格式
// extended: true   方法内部使用第三方模块 qs 来处理请求参数的格式
app.use(bodyParser.urlencoded({extended: false}));

app.post('/index', (req, res) => {
    // req.query 获取请求参数
    res.send(req.body)
})

// 监听端口
app.listen(80,()=>{
    console.log('http://127.0.0.1')
});

请添加图片描述

方法二:

// 配置解析表单数据的中间件
app.use(express.urlencoded({extended:false})) // 解析application/x-www-form-urlencoded格式的表单数据
app.use(express.json())  // 解析json格式的表单数据
  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值