Node.js教程
Posted 薛帅
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Node.js教程相关的知识,希望对你有一定的参考价值。
目录
第一章 认识Node.js
1.1 安装node
http://nodejs.cn/download/
检验是否安装完成
打开终端输入以下命令,是否出现版本号
- node -v
- npm -v
1.2 node示例
- const os = require(‘os‘);
-
- // 读取系统的cpu的信息
- const cpus = os.cpus(); //获取当前系统的cpu的数量
- console.log(cpus.length);
-
- //获取内存信息
- const total = os.totalmem();//bytes
- console.log(total/1024/1024/1024);//GB
-
- //获取剩余内存信息
- const free = os.freemem();
- console.log(free/1024/1024/1024);//GB
运行程序
终端输入
node demo.js(文件名)
1.3 第一个node程序
- const http = require(‘http‘);//创建http模块
- const hostname = ‘127.0.0.1‘;//主机地址
- const port = 3000;//端口号
-
- //创建一个server实例
- const server = http.createServer((req,res)=>{
- //req:请求对象
- //res:响应对象
- res.statusCode = 200;
- res.setHeader(‘Content-Type‘,‘text/plain‘);
- res.end(‘hello World‘);//返回到页面
- })
- server.listen(port,hostname,()=>{
- //回调
- console.log(`服务启动成功,监听端口:${port}`)
- })
页面上返回如下
终端打印如下
1.4 Supervisor介绍
我们一般都是编写代码边调试,这个过程很繁琐,Supervisor是个工具,可以帮我们自动检测代码的变化,重启服务
全局安装supervisor
npm install supervisor -g
安装完成启动项目使用
supervisor base.js(文件名)
1.5 nrm和nvm介绍
nrm管理npm源
- nrm ls //查看所有的源
- nrm current //当前使用的源
- nrm use <源名称> //切换源
- nrm add <registry> <url> [home] //添加自定义源
安装nrm
npm install nrm -g
nvm管理node.js版本
nvm ls //查看电脑上所有的node版本
第二章 Node.js基础知识
2.1 web应用和第一个express应用
web应用
ajax,websockt --> 服务器(web应用) --> 缓存/数据库
通过ajax或者其他方法请求web应用获取数据
express框架
express
接收 req,处理 res
是node中的一种web框架
首先需要先安装express
- npm install express -S //生产环境下安装express
- 或者使用 npm install //安装所有依赖
- const express = require(‘express‘);
-
- //是一个express实例
- const app = express();
-
- //get请求
- //请求/name接口的时候需要跟个参数。例:/name/123
- //返回 {name:tom,age:123}
- app.get(‘/name/:age‘,(req,res)=>{
- let {age} = req.params;
- res.json({
- name:‘tom‘,
- age
- })
- })
-
- //post请求
- app.post(‘/name‘,(req,res)=>{
- res.send(‘tom post‘)
- })
-
- //所有请求
- app.all(‘/name‘,(req,res)=>{
- res.send(‘tom all methods‘)
- })
-
- app.listen(3000,()=>{
- console.log(‘server 启动成功‘)
- })
2.2 Route介绍和使用
web服务如何处理一个请求?
url --> 网络 --> dns解析 --> 目标服务器
如何响应这个请求 --> 路由//规则
1. 请求方法来区分
- get --> 响应
- post --> 响应
2.通过uri --> 路径区分(域名后面的路径)
www.baidu.com/a/b/c.html
2.3 express路由演示
路由的区分实例
请求方法区分
- app.get(‘/demo‘,(req,res)=>{
- //req:请求对象
- //res:服务器响应对象
- res.json({
- message:‘hello express route from get demo‘
- })
- })
- app.post(‘/demo‘,(req,res)=>{
- //req:请求对象
- //res:服务器响应对象
- res.json({
- message:‘hello express route from post demo‘
- })
- })
uri 区分
- app.get(‘/user/byname‘,(req,res)=>{
- let {name} = req.query;
- res.json({
- name
- })
- })
- app.get(‘/user/byid‘,(req,res)=>{
- let {id} = req.query;
- res.json({
- id
- })
- })
2.4 express路由API使用(一)
1:需要定义一个api/路由,需要满足客户端无论使用什么请求方式都可以得到响应
- app.all(‘/demo‘,(req,res)=>{
- res.json({
- message:‘demo‘,
- method:req.method
- })
- })
2:无论客户端使用任何的uri,我们的服务器都可以响应--> 日志
- app.all(‘*‘,(req,res)=>{
- res.json({
- message:‘demo‘,
- method:req.method,
- uri:req.path
- })
- })
2.5 express路由API使用(二)
app.use --> 使用中间件(可以用来写路由,但是尽量写中间件,因为路由也属于中间件)
- app.use(‘/demo‘,(req,res)=>{
- res.json({
- message:‘demo‘,
- method:req.method
- })
- })
- app.use(‘/demo‘,(req,res)=>{
- res.json({
- message:‘demo‘,
- method:req.method,
- uri:req.path
- })
- })
2.6 路由拆分
member
sku
order
这三个路由都有一个子路由list
- 定义一个文件
member.router.js
2. 在该文件中写入所要处理的子路由(包括express框架)
- 和app中的路由写法一致
- router.[method] //get post ...
- router.all
- router.use
-
- const router = express.Router(); //引入路由
- router.get(‘/list‘,(req,res)=>{
- res.json({
- {
- id:001,
- name:‘张三‘
- }
- })
- })
- module.exports = router; //将该路由暴露出去
3. 进入入口文件(app.js)注册路由
- const memberRouter = require(‘./member.router‘); //引入刚才写好的member路由文件
- const skuRouter = require(‘./sku.router‘); //引入刚才写好的sku路由文件
- //注册路由
- app.use(‘/member‘,memberRouter) // /member作为父级
- app.use(‘/sku‘,memberRouter) // /sku作为父级
2.7 中间件
什么是express中间件
- 是一个函数
- 有四个参数(err,req,res,next),next是个回调
- function demo_middleware(err,req,res,next){
- //1. 异常
- //2. 处理业务功能,然后转交控制权--next
- //3. 处理响应--结束响应-->当作路由的处理函数
- }
- app.all(‘*‘,valid_name_middleware)
-
- //当调这个接口的时候,会先进入到all方法,然后执行中间件
- //判断是否有name参数,如果没有则执行中间件中返回的东西
- //如果有则进入next回调,执行该执行的东西
- app.get(‘/test‘,(req,res)=>{
- res.json({
- message:‘test‘
- })
- })
-
- //中间件,检验是否有name参数
- function valid_name_middleware(req,res,next){
- let {name} = req.query;
- if(!name || !name.length){
- res.json({
- message:‘缺少name参数‘
- })
- }else{
- next();
- }
- }
内置中间件和第三方中间件介绍
使用方式:
- app级别
-
注册的时候,一定在最顶级
-
app.use --> api去加载进来
- function log_middleware(req,res,next){
- console.log(‘请求来了。。。‘);
- next();
- }
- app.use(log_middleware); //注册app级别的中间件
-
- //加载一个static的中间件(内置的),会去访问static下面的html文件
- app.use(express.static(‘static‘,{
- extensions:[‘html‘,‘htm‘]
- }))
2.router级别
- //1- 第一个场景
- router.use(function(req,res,next){
- console.log(‘log from router‘);
- next();
- })
- //2- 路由内部使用
- function vlaid_login_params(req,res,next){
- let {name,password} = req.query;
- if(!name || !password){
- res.json({
- message:‘参数校验失败‘
- })
- }else{
- req.formdata = {
- name,
- password
- }
- next();
- }
- }
- router.get(‘/login‘,[/** middleware */],(req,res)=>{
- let {formdata} = req;
- res.json({
- message:‘login‘
- })
- })
3.异常处理-->app级别-->router级别
自定义中间件
2.8 异常处理
异常捕获
express内置异常处理
自定义异常处理
- app.get(‘/demo‘,(req,res)=>{
- throw new Error(‘测试异常功能‘)
- })
-
- function demo_middleware(req,res,next){
- try{
- // mysql操作
- }catch(error){
- next(error);
- }
-
- //Promise.then().catch(next)
-
- //将异常抛到最终的异常处理器上
- //异常处理一定是收口的
- }
-
- //异常处理
- function error_handler_middleware(err,req,res,next){
- if(err){
- let {message} = err;
- req.status(500)
- .json({
- message:`${message || ‘服务器异常‘}`
- })
- }
- }
- //处理404
- function not_found_handler(req,res,next){
- res.json({
- message:‘api不存在‘
- })
- }
- app.use(not_found_handler)//处理404异常
- app.use(error_handler_middleware) //异常处理放在最底部
2.9 MySQL
结构化数据库中的一种
是一个服务,提供了数据存放的服务
mysql的安装
2.10 Sequelize介绍和使用
安装sequelize
- npm install sequelize -S //生产环境安装
- npm install sequelize-cli -S //安装scli-equelize-cli提高效率
- npx sequelize-cli init //初始化sequelize
初始化完成会生成如下文件
- config 目录
- migrations 数据迁移文件
- modeules ORM里面的每个模块会跟我们的项目关联
- seeders 初始化脚本
修改config配置文件
- "development": {
- "username": "root",//用户名
- "password": null,//密码
- "database": "database_development",//数据库名
- "host": "127.0.0.1",//主机地址
- "dialect": "mysql"//方源
- }
npx sequelize-cli model:generate --name User --attributes name:string
完成之后
models目录下会多一个user.js文件
migrations目录下会多一个文件,这个文件就是用来创建表
- const models = require(‘../models/‘); //模型对象
- //models.User //User模型
- //models.Sequlize //Sequlize类
- //models.sequlize //sequlize实例
-
- npm install mysql2 -S //安装驱动连接MySQL
- npx sequelize-cli db:migrate --env=development //创建表
- //创建表中记录
- app.get(‘/create‘,async (req,res)=>{
- let {name} = req.query;
- // promise user --> sequlize对象
- let user = await models.User.create({
- name
- })
- res.json({
- message:‘创建成功‘,
- user
- })
- })
- //查询表中所有的数据
- app.get(‘/list‘,async (req,res)=>{
- let list = await models.User.findAll();
- res.json({
- list
- })
- })
- //
- //查询表中id为传入id的数据
- app.get(‘/detail/:id‘,async (req,res)=>{
- let {id} = req.params;
- let user = await models.User.findOne({
- where:{
- id
- }
- })
- res.json({
- user
- })
- })
第三章 从实战中熟悉操作
3.1 需求分析
第一步根据用户所提出来的需求进行分析,这一步很重要,分析完成才可以设计你的API
主要分析需要传进来什么参数,实现什么功能
3.2 API设计
- 创建项目目录
- 初始化npm
npm init
3.安装依赖
npm install express mysql2 sequelize supervisor sequelize-cli body-parser -S
4.先把框架写出来
- >> app.js
- const express = require(‘express‘);
- const bodyParser = require(‘body-parser‘);//post请求需要该中间件
- const app = express();
-
- app.use(express.json());
- app.use(express.urlencoded());
- app.use(bodyParser.urlencoded({extended: true}));
-
- app.listen(3000,()=>{
- console.log(‘服务启动成功‘)
- })
5.异常处理,所有的错误,http status == 500
- app.use((err,req,res,next)=>{
- if(err){
- res.status(500).json({
- message:err.message
- })
- }
- })
6.API的设计
- app.get(‘/list/:status/:page‘,async (req,res,next)=>{
- res.json({
- list:[]
- })
- })
- /*创建一个任务*/
- app.post(‘/create‘,async (req,res,next)=>{
- let { name,deadline,content } = req.body;
- res.json({
- todo:{},
- name,
- deadline,
- content
- })
- })
- /*修改一个任务*/
- app.post(‘/update‘,async (req,res,next)=>{
- let { name,deadline,content,id } = req.body;
- res.json({
- todo:{},
- name,
- deadline,
- content,
- id
- })
- })
- /*修改一个todo,删除*/
- app.post(‘/update_status‘,async (req,res,next)=>{
- let { id,status } = req.body;
- res.json({
- todo:{},
- id,
- status
- })
- })
3.3 模型创建
1.数据库的初始化
- 创建数据库
- 使用`sequelize-cli`初始化项目的数据库配置信息 `npx sequelize init`(建议新建一个目录)
- 生成模型文件
- 1.migrate 文件
- 2.model 文件
- `npx sequelize model:generate --name Todo --attributes name:string,deadline:date,conten:string`
- 持久化,模型对应的[数据库表] (生成数据库表)
- `npx sequelize db:migrate`
2.API里面具体使用ORM模型
3.4 API里面具体使用ORM模型
- const models = require(‘../db/models‘); //导入模型
-
- /*创建一个todo*/
- app.post(‘/create‘,async (req,res,next)=>{
- try{
- let { name,deadline,content } = req.body;
- /**数据持久化到数据库**/
- let todo = await models.Todo.create({
- name,
- deadline,
- content
- })
- res.json({
- todo:{},
- name,
- deadline,
- content
- })
- }catch (error){
- next(error);
- }
- })
- /*修改一个todo*/
- app.post(‘/update‘,async (req,res,next)=>{
- try{
- let { name,deadline,content,id } = req.body;
- let todo = await models.Todo.findOne({
- where:{
- id
- }
- });
- if(todo){
- //执行更新功能
- todo = await todo.update({
- name,
- deadline,
- content,
- id
- })
- }
- res.json({
- todo
- })
- }catch(error){
- next(error);
- }
- })
- /*修改一个todo,删除*/
- app.post(‘/update_status‘,async (req,res,next)=>{
- try{
- let { id,status } = req.body;
- let todo = await models.Todo.findOne({
- where:{
- id
- }
- });
- if(todo && status != todo.status){
- //执行更新功能
- todo = await todo.update({
- status
- })
- }
- res.json({
- todo
- })
- }catch(error){
- next(error);
- }
- })
3.5 运维和发布
服务要启动在后台,不能在窗口
pm2工具
- npm install pm2 -g //全局安装pm2
- pm2 init //初始化pm2 生成ecosystem.config.js文件
- ecosystem.config.js文件中apps可以有多个应用
第四章:总结与问题归纳
4.1 总结
- 1.技术栈
- node --> http,异常
- web框架,express、hapi、koa、egg
- 参数校验
- mysql的使用,了解
- ORM,sequelize使用
- 2.技术关键点
- api设计
- web-->webserver-->router-->hander-->orm--db
- 3.注意事项
- 需要做详细的 模型设计-->模型之间的关系
- api的使用文档-->api文档的实用工具
- 测试
4.2 问题归纳
注意:一旦删除了自带的createdAt和updatedAt两个字段,需要做出如下设置
- >> models >> user.js
- module.exports = (sequelize, DataTypes) => {
- const User = sequelize.define(‘User‘, {
- name: DataTypes.STRING
- }, {
- timestamps:false //添加这行代码,改变sequelize的默认字段为false
- });
- User.associate = function(models) {
- // associations can be defined here
- };
- return User;
- };
修改字段默认值
- >> models >> user.js
- const User = sequelize.define(‘User‘, {
- name: DataTypes.STRING,
- status:{
- type:DataTypes.InTEGER,
- defaultValue:1 //可以在这里修改默认值
- }
- }, {
- timestamps:false
- });
以上是关于Node.js教程的主要内容,如果未能解决你的问题,请参考以下文章
node.js零基础详细教程:node.js操作mongodb,及操作方法的封装
HTTP 状态代码 200 但页面未加载 Node.js Socket.io -- 使用 Socket.io 的 Node.js 教程,Daniel Nill,fs.readFile(),socket