# node-js-learn **Repository Path**: qq2528825468/node-js-learn ## Basic Information - **Project Name**: node-js-learn - **Description**: node-js 学习,vue前置知识点 - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-09-29 - **Last Updated**: 2022-11-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README node-js-learn: 一:初始node.js 1.介绍: Node.js® 是一个基于 Chrome V8 引擎 的 JavaScript 运行时环境。 2.做什么 nodejs作为JavaScript运行环境只提供了基础的功能和api,但是在此基础上出了很多工具和框架 express快速构建web应用 electron构建跨平台桌面应用 restify快速构建api接口项目 ... 3.咋么学 JavaScript基础语法-nodejs内置api模块(fs、path、http...)-第三方模块(express、mysql) 二:使用node.js模块 1.fs模块-操作文件 fs.readFile(path[,options],callback) 路径、编码格式、回调函数获取读取数据 fs.writeFile(file,data[,options],callback) 路径、编码格式、回调函数获取读取数据 2.路径问题: 相对路径并不是针对js文件的路径,而是根据执行node 命令是所处的目录为当前目录,所以相对路径很容易写错 基于这个原因,所以多用绝对路径或者变量存储路径 __dirname表示当前文件的绝对路径 3.__dirname可以使用+进行字符串拼接,但更推荐使用path模块进行路径操作 node提供的对路径处理的模块 const path = require('path') path.join([,path]) //获取路径 path.basename(path[,extname]) //获取文件名 带有可选参数则文件名将不带后缀标记 path.extname(path) //获取文件后缀名 4.path模块的案例 将时钟案例index.html中拆分为html js css三个文件 步骤: 1.使用正则表达式匹配style标签和script标签 2.使用fs模块读写要处理的index.html文件 3.自定义写入方法分别写入index.html index.js index.css 案例: 02-path模块 5.http模块 1.介绍: 官方提供创建web服务器的模块对外可进行提供服务 2.使用 导入require('http') 创建web实例 绑定request监听事件 启动服务器 3.案例 03-http模块 四:模块化 1.分类: 内置模块、自定义模块、第三方模块 2.模块作用域 自定义模块中的变量、方法等成员值只能在当前模块内被访问 3.自定义模块 module对象,属于模块的内部对象任何一个js都有module对象展示当前模块的信息 module.exports对象可以将模块内的成员对外提供出去 外界通过require引入自定义模块时得到的就是module.exports所指向的对象,默认为空对象 4.exports对象 默认情况下module.exports和exports是同一个对象 最终暴露出去的以module.exports对象为准 这里要注意,如果直接使用exports={}这样写的话相当于给exports重新指向了一个自定义对象,这样写会破坏node.js所封装的 module.exports和exports是同一个对象 5.commonJS模块规范 每个模块内部,module变量代表当前模块 module变量是一个对象,module.exports属性是对外的接口 require用于加载某个模块,所加载的就是module.exports 6.案例 04-模块化 五:npm与包 1.包: 别人基于内置模块写的,开源的模块,比内置模块功能高级点... 2.npm 包管理工具,随着node.js下载会默认安装 命令窗口 npm -v 可以看版本 3.搜索包 https://www.npmjs.com/ 4.下载包 使用Node Package Manager 就是npm 会从服务器上去下载所需要的包 npm i package_name@version 5.上传包 1.准备一下文件 package.json包管理配置文件 index.js入口文件 readme.md说明文档 2.注册npm账号,网页注册 3.终端中登陆npm账号,如果换过仓库地址要先改回去 nrm use npm,终端 npm login 4.发布 npm publish 5.删除72h内发布的包且24h内不允许再次重复发布,72h之后永久不可删除,如果练习尽量发完之后删掉 npm unpublish 06-npm-upload --force 6.注意事项说明 node_modules 文件夹存已经安装的包,用于require导入 package-lock.json 配置文件,存放已安装包的下载信息 name version download_url... 新安装的包会覆盖掉原来的包,不指定版本号会安装最新版本,版本规范,点分十进制的三位数字 大版本.功能版本.bug修复 node_modules配置文件应存在于项目根目录下面记录相关信息 node_modules需要放到gitignore中,第三方的包文件一般不用于团队共享 通过package.json (npm init -y 可以生产该文件)记录共享包信息 加载package.json的包(npm install 可以安装package.json下的所有包) 这些文件避免手动修改,属于npm自动维护 7.案例 05-npm包 06-npm-upload 六:模块加载机制 1.加载顺序: 先招内置模块、再找当前模块的node_modules,找不到再往上级目录找 同一个js中引入模块,优先从缓存中进行加载,多次require不会重复读取硬盘数据 2.重命处理 如果第三方模块和内置模块存在重命,则内置模块的加载优先级高于第三方模块 3.加载写法 自定义模块,require中需要指定路径标识符 4.省略写法 如果省略文件后缀名,则分别查找 无后缀名、 .js、 .json、 .node 的拓展名进行匹配,都加载失败抛出异常 如果加载目录、则在目标目录中寻找package.json文件的main入口,如果不存在则寻找index.js 找不到抛出异常 六:express 1.介绍 基于 Node.js 平台,快速、开放、极简的 Web 开发框架 本质上是个npm包,比http模块好用...类似js-->jQuery 常用开发api接口服务器或者网站服务器 2.接收请求做出响应 安装 npm i express 导入 const express = require('express') 创建实例 const app = express() 启动服务监听端口 app.listen(80,()=>{ console.log('express server start listen 80 now') }) 监听get/post请求 app.get/post('request_url',(req,res)=>{console.log('request_url trigger')}) 获取参数 req.query req.params 返回响应信息 res.send(响应内容) 3.托管静态资源 app.use([可选参数 指定目录前缀],express.static('静态资源目录')) app.listen(80, () => { console.log('express server start listen 80 now') }) 如果需要公开多个目录可以多次调用app.use方法 如果公开的目录中有重名的资源,则会按照顺序展示找到的第一个资源 4.nodemon插件 用于代码改动后自动重启node.js 安装 npm install -g nodemon 使用 node xxx.js 改为 nodemon xxx.js 2.路由 客户端请求和服务端处理函数之间的对应关系 路由包含三部分,请求方式、请求地址、处理函数 格式 app.METHOD('REQUEST_URL',FUNCTION(req,res)) 3.路由模块化 不建议直接将路由挂载到app中,推荐将路由抽离成单独的模块 创建路由模块.js文件,使用express.Router()获取路由实例对象 向路由对象挂载具体路由 使用module.express将路由对象提供给外部使用 通过app.use([可选访问前缀,] route)注册路由模块 //导入express包 const express = require('express') //实例化路由对象 const router = express.Router() //路由挂载 router.get('/router',(req,res)=>{ res.send(req.url+'||trigger||req.query='+JSON.stringify(req.query)) }) //暴露路由对象 module.exports = router 3.中间件 app.use()本质上就是注册一个全局中间件 请求到达express时可以调用多个中间件对请求进行预处理 express中间件实际上是一个function函数,且参数中包含next(函数)参数并会被执行,路由处理没有next参数 定义中间件函数: function(req,res,next){next()} 注册全局中间件 app.use(中间件函数) 注册中间件函数作为全局中间件 中间件函数需要在路由之前注册,多个中间件按顺序执行 注册局部中间件 app.get('请求地址',中间件函数1,中间件函数2...,路由处理函数) 注意事项: 是有路由之前注册中间件 中间件可以连续多次注册 中间件函数最后一定是next()且next()之后不允许包含其它代码 4.中间件分类 应用级 通过app.use() 或者app.get() app.post()绑定到app实例上面的中间件称为应用级中间件 路由级 通过express.Router()绑定到路由模块上的中间件,进一步通过app.use('路径',router)的方式称为路由级中间件 错误级 指的是中间件函数有四个参数 function(err,req,res,next),放在所有路由之后且只能使用全局注册的方式 app.get('/error', (req, res) => { //路由处理函数 throw new Error('自定义抛出异常') res.send(req.url+'||trigger||req.query='+JSON.stringify(req.query)) }) app.use( function(err,req,res,next){ //中间件处理函数 console.log('err.message:'+err.message) res.send('err function') }) 也可以使用路游级的注册方法注册错误级中间件函数,没有错误不会调用错误级中间件函数 express内置 4.16.0之后有了仨内置的中间件 express.static(静态资源目录) 托管静态资源文件 express.json() 解析json解析请求体 app.use(express.json()) express.urlencoded() 解析url-encoded格式请求体 app.use(express.urlencoded({extended:false})) 第三方 npm install 第三方中间件名称 比如说body-parser ,内置的express.urlencoded 就是借鉴的 body-parser.urlencoded require('第三方中间件名称') app.use(第三方中间件) 自定义中间件 定义中间件 模拟express.urlencoded解析post表单数据 app.use(function(req,res,next){}) 监听req的data事件和end事件,开始发送数据和数据发送完毕 使用querystring对数据进行解析 解析数据挂载到req.body (企业级注意模块化拆分 抽出中间件函数单独一个js文件) const router_myfunctionn = express.Router() //路由级中间件函数 router_myfunctionn.use(function(req,res,next){ let str = '' //监听data数据并记录 req.on('data',(chunk)=>{ str += chunk }) //监听数据传送完毕事件 req.on('end',()=>{ const body = qs.parse(str) req.body=body console.log('数据解析完毕='+JSON.stringify(body)) next() //此处的next函数若放到外层会导致异步的情况出现,后面的处理函数不能拿到req.body属性 }) }) //路由挂载 router_myfunctionn.post('/router_myfunctionn',(req,res)=>{ console.log('返回路由层') console.log(req.body) res.send(req.url+'||trigger||req.query='+JSON.stringify(req.query)) }) app.use(router_myfunctionn) 5.接口 使用: 1.导入express,创建服务器并启动端口监听 2.创建api路由模块 3.创建get/post请求接口 //导入express包 const express = require('express') //创建服务器 const app = express() //启动服务器 app.listen(80,()=>{ console.log('http port 80 server start') }) //创建api路由 const router = express.Router() //设置路由请求处理 router.get('/router',(req,res)=>{ res.send({ url:req.url, dataStr:JSON.stringify(req.query), data:req.query }) }) //路由挂在到app app.use(router) 跨域问题解决1: npm install cors //安装 const cors = require('cors') //导入 app.use(cors())//路由之前调用 说明:cors通过修改响应头解除浏览器的同源安全访问策略,默认可对9个常用请求头进行修改, 如果客户端需要向服务端发送自定义head需要在服务端进行显示声明 使用cors的请求分为简单请求和预检请求,在正式发起请求前会发送一个option方式的预检请求 -------------------------------------------------------------- 如果是在node.js服务端中使用jQuery的ajax出现跨域 可以使用request模块进行请求...服务端的请求 那有什么跨域一说,跨域是在浏览器上出的问题 const request = require('request'); const options = { url: 'http://www.baidu.com/s?wd=test', method:"GET", } request(options, function (error, response, body) { if (!error && response.statusCode === 200) { //拿到实际请求返回的响应头,根据具体需求来设置给原来的响应头 let headers = response.headers; console.log(headers); console.log(body) } else { res.send(options); } }); 跨域问题解决2: 使用jsonp进行解决,该方案只能对get请求有效目前已渐渐淘汰 原理在与动态生成script标签并在src赋值请求地址和callback回调函数 服务端在接受请求时可以获取回调函数并进行调用将数据写入到回调函数中 客户端可通过回调函数获取数据 七:mysql 1.安装: npm install mysql 2.创建连接: ...此部分不写了,mysql模块上次更新时间为2019年且并不支持mysql8的认证方式(当然可以通过配置调整) 而且也没啥好说的,就跟jdbc一样很基础,创建连接 执行SQL 获取执行结果 查看执行效果... 七:session 1.安装 npm install express-session 2.使用 中间件使用,配置之后可以通过req.session获得session信息域 八:jwt 1.安装 npm install jsonwebtoken express-jwt 2.使用 jsonwebtoken 将用户信息生成加密字符串 express-jwt 解析字符串为用户信息 九:案例 由于练习使用,就不使用数据库了,所有数据都直接在后台进行模拟