Node.js 学习笔记

一、Node.js

1.简介:

​ node.js 是一个名词,不是技术,技术语言:JavaScript

​ 目标:让JavaScript可以操作服务器

​ 场景:博客,聊天室

2.特点:

Node.js------解决服务器高性能瓶颈问题

1.单线程:仅仅使用一个线程,当用户连接,就触发一个内部事件,通过异步非阻塞I/O、事件驱动机制。在宏观上程序也是并行的。

2.非阻塞I/O:异步操作数据库。

3.事件驱动:通过“ 事件环 ”机制,处理事务。底层代码近半数都用于事件队列、回调函数队列的构建,用事件驱动完成服务器的任务调度。

3.使用

windows+R 运行窗口

输入cmd,进入窗口命令

输入noed node文件名在此运行

VsCode运行:右键点击文件,选择在终端运行,启动命令窗口

常见的窗口命令:

tab 自动补全 cls 清空命令窗口

Ctrl+C 退出运行环境 dir查看当前目录下文件

cd 进入文件

运行node文件:node+ 空格+文件名

4.基本Demo

// 1.引入服务 http协议
const http=require('http');
// 设置端口号和域名
const hostname = '127.0.0.1';
const port = 3000;

// 2.创建服务器
const server=http.createServer((req,res)=>{
  // req  request请求数据   res respond响应的数据

  // 给客户端响应数据
  res.setHeader('Content-Type', 'text/plain;charset=utf8');
  //客户端输出
  res.end('你好,这是Node.js的Demo');
});

// 3.监听服务
server.listen(port,hostname,()=>{
  console.log(`服务器开启了,客户端可以访问了,端口号${port},域名为${hostname}`);
});

5.Nodejs的Commonjs规范

js文件间不可以直接访问

如何访问?

拥有数据的data.js文件

//暴露出去
module.exports={
	uname:'付常涛',
    color:'red'
}

对应的使用数据的js文件 ./必须带,后缀可省略

// 使用data.js中的数据
let data=require('./data');
console.log(data);

6.其他服务

6.1 querystring模块

​ 提供用于解析和格式化 URL查询字符串的实用工具

//1.引入querystring模块,提供用于解析和格式化 URL查询字符串的实用工具
let query=require('querystring');

// 对象
const obj={
    uname:'fct',
    age:12,
    mima:456
}
// 字符串
let str='username=qq&password=123';

// 2.把对象转换成字符串
console.log('对象转字符串:',query.stringify(obj));
// 3.把字符串转换成对象
console.log('字符串转对象:',query.parse(str));

6.2 url模块

​ 用于处理与解析URL

//url模块用于处理与解析URL
const url=require('url');

// 模拟获取URL地址
const str='https://user:pass@sub.host.com:8080/p/a/t/h?query=uname=fct#hash';

// 把地址解析 url.parse();
let newStr=url.parse(str);
console.log(newStr);

//获取URL地址中query信息
const query=require('querystring');
let obj=query.parse(newStr.query);
console.log(obj);

7.安装淘宝镜像

7.1 npm下载

npm是node提供的包管理工具

npm下载node-module依赖的管理工具

npm下载依赖的包 服务器国外 下载框架 速度慢

通过npm获取
npm install xxxxxxx

7.2 cpnm下载

cnpm 淘宝镜像 服务器国内 速度快

安装cnpm:

npm install -g cnpm --registry=https://registry.npm.taobao.org

安装完毕检测成功与失败:
输入cnpm

不打印:”不是内部或者外部命令,也不是可运行的程序或批处理文件”说明成功了

二、Express

基于Node.js平台,快速、开放、极简的Web开发框架

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

1.安装

  1. 创建一个项目,目录文件名,并进入该文件

  2. 通过npm init命令为你的应用创建一个 package.json文件

    npm init
    
  3. 安装Express并将其保存到依赖列表中

    npm install express --save
    或
    cnpm install express --save
    
  4. 执行demo文件,创建index.js

    //index.js
    const express = require('express')
    const app = express()
    const port = 3000
    
    app.get('/', (req, res) => {
      res.send('Hello World!')
    })
    
    app.listen(port, () => {
      console.log(`Example app listening at http://localhost:${port}`)
    })
    
  5. 终端执行

    node index.js
    
  6. 打开浏览器,访问localhost:3000,本地开启的服务

2.扩展工具postman

模拟网络请求getpostdeleteput

浏览器扩展工具:postman

3.Express路由

不同网络请求

// 1.引入express
const express=require('express');

// 2.创建服务
const app=express();

// 路由1:
app.get('/',(req,res)=>{
    res.send('<h2>首页</h2>');
})
// 路由2;post登录
app.post('/login',(req,res)=>{
    res.send({
        uname:'fct',
        password:'123fct',
        info:'登陆成功啊!'
    })
})
// 路由3:put 修改
app.put('/edit',(req,res)=>{
    res.send('修改成功');
})
// 路由4:delete 删除
app.delete('/remove',(req,res)=>{
    res.send('删除成功');
})

// 3.设置事件监听
app.listen(4000,()=>{
    console.log('端口号:',4000,',服务启动');
})

4.Express 托管静态文件

为了提供诸如图像、CSS 文件和 JavaScript 文件之类的静态文件,请使用 Express 中的 express.static 内置中间件函数

const express=require('express');

const app=express();
// 路由:首页
app.get('/',(req,res)=>{
    res.send('首页');
})

// 静态文件托管
// 将 common 目录下的图片、CSS 文件、JavaScript 文件对外开放访问了
// 1.
/* app.use(express.static('common'));
// http://localhost:3000/css/base.css 
// http://localhost:3000/img/pic1.jpeg  */

// 2.
app.use('/static',express.static('common'));
/* http://localhost:3000/static/css/base.css
http://localhost:3000/static/img/pic1.jpeg*/



app.listen(3000,()=>{
    console.log('服务已启动!');
})

5.Express_Router文件配置

router.js

// 路由文件
// 配置页面的走向

// 1.引入Express
const express=require('express');
// 2.创建路由
const router=express.Router();

// 路由配置
router.get('/',(req,res)=>{
    res.send('首页的界面');
})
router.get('/news',(req,res)=>{
    res.send('新闻的界面');
})
//导出路由
module.exports=router;

index.js

const express=require('express');

const app=express();
// 引入Router文件
const router=require('./router');

//app使用Router
// app.use(router);
app.use('/',router); //与上面等价
// http://localhost:3000
// http://localhost:3000/news
app.use('/res',router);
// http://localhost:3000/res
// http://localhost:3000/res/news

app.listen(3000,()=>{
    console.log('端口号',3000,'的服务启动!');
})

6.参数传递

6.1get传递参数

URL地址栏传递参数

// 获取URL库
const url=require('url');

// 访问get---带参数
app.get('/news',(req,res)=>{
    // 接受参数
    //url.parse(地址,query是否转对象)
    let str=url.parse(req.url,true);
    
    const data=str.query;//query数据字段

    /* res.send({
        msg:'新闻信息',
        // data:data
        name:data.uname,
        psw:data.psw
    }); */
    if(data.title){//当参数有title时
        res.send({
            msg:'新闻界面',
            dataUrl:data.title
        })
    }else{
        res.send({
            msg:'参数传递失败'
        })
    }
})

6.2 post传递参数

// post传递参数--中间件
// 引入中间件
let bodyParser=require('body-parser');
// 应用中间件
app.use(bodyParser.urlencoded({
    extended:true
}));

// post请求
app.post('/login',(req,res)=>{
    // 接收参数
    const uname=req.body.username;//username:定义接收的变量
    const psw=req.body.password;//username:定义接收的变量
    if(uname=='admin'&&psw=='123'){
        res.send({
            msg:'登陆成功',
            username:uname,
            password:psw
        });
    }else{
        res.send({
            msg:'账号或密码错误',
        });
    }
})

6.3 参数传递-----掌握

// 1.get参数传递
app.get('/list',(req,res)=>{
    // 直接获取参数
    const data=req.query;
    console.log(data);
    res.send({
        msg:'列表信息',
        uname:data.uname,
        sex:data.sex,
        age:data.age
    });
});

// 2.post 参数
// post中间件
app.use(express.urlencoded({extended:true}));

app.post('/login',(req,res)=>{
    let uname=req.body.username;
    let psw=req.body.password;
    res.send({
        msg:'登录成功',
        name:uname,
        upsw:psw
    })
})

// 3.新传参--restful API   get传递参数的一种方式
//知乎:get参数: https: //www.zhihu.com/question/397426376/mima/123
//参数: xxxx/id/xxx/mima/xxX
//传统的get参数:xxxx ?uname=qq&mima=123
app.get('/zhihu/question/:question/mima/:mima',(req,res)=>{
    // params
    const question=req.params['question'];
    const mima=req.params['mima'];
    res.send({
        question:question,
        mima:mima
    });
    // http://localhost:3000/zhihu/question/今天你开心嘛?/mima/123
})

7.跨域

Node.js实现(express)--------------cors资源共享

7.1 单一路由,跨域

router.get('/list', (req, res) => {
    // 设置cors资源共享
    //设置允许跨域的域名,*代表允许任意域名跨域
    res.header("Access-Control-Allow-Origin","*");
    res.send(data);
})

7.2 全局资源共享

// 配置全局资源共享
router.all("*", function (req, res, next) {
    //设置允许跨域的域名,*代表允许任意域名跨域
    res.header("Access-Control-Allow-Origin", "*");
    //允许的header类型
    res.header("Access-Control-Allow-Headers", "content-type");
    //跨域允许的请求方式 
    res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS");
    if (req.method.toLowerCase() == 'options')
        res.send(200); //让options尝试请求快速结束
    else
        next();
})

三、Nodejs连接数据库

1.基本配置

1.1安装:

npm install mysql --save

1.2 配置

//引入数据库
const mysql=require('mysql');
//连接数据库 
/**语法:
 * mysql.createConnection({
     host:'',//域名 本地地址
     user:"",数据库的账号
     password:"",数据库的密码
     database:""数据库
     port:"3306" 数据库端口号  默认不写
})
 */
const client=mysql.createConnection({
    host:'localhost',
    user:'root',
    password:"123",
    database:"php_test"
})

//查询语句
const sql="select * from info";

//执行sql语句
//语法:  client.query(sql,callback) 
client.query(sql,function(err,result){
    if(err){
        console.log('操作失败');
        return;
    }else{
        console.log(result);
    }
})

2.Nodejs+Express+MySQL+Html

完成前端页面连接本地服务器和结合数据库,进行表单验证

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>表单验证--Nodejs——Express</title>
</head>
<body>
    <p>控制台观看---结果</p>
    <h2>登录接口</h2>
    <input type="text" id='uname'>
    <input type="text" id='mima'>
    <button id='login'>登录</button>
    
    <h2>注册接口</h2>
    <input type="text" class='uname'>
    <input type="text" class='mima'>
    <button class='register'>注册信息</button>

    <h3>修改密码</h3>
    账号:<input type="text" class='username'>
    密码:<input type="text" class='password'>
    新密码:<input type="text" class="newmima">
    <button class='update'>确认修改</button>

    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
    <script>
        // 登录
        $('#login').click(()=>{
            let name=$('#uname').val();
            let psw=$('#mima').val();
            console.log(name,psw);
            $.ajax({
                type:'post',
                url:'http://localhost:3000/login',
                data:{
                    name:name,
                    psw:psw
                },
                success:(res)=>{
                    console.log(res);
                }
            });
        });
        
        // 注册
        $('.register').click(()=>{
            let name=$('.uname').val();
            let psw=$('.mima').val();
            console.log(name,psw);
            $.ajax({
                type:'post',
                url:'http://localhost:3000/register',
                data:{
                    name:name,
                    psw:psw
                },
                success:(res)=>{
                    console.log(res);
                }
            });
        });
        
        // 修改密码
        $('.update').click(()=>{
            let name=$('.username').val();
            let psw=$('.password').val();
            let newPsw=$('.newmima').val();
            console.log(name,psw,newPsw);
            $.ajax({
                type:'post',
                url:'http://localhost:3000/alter',
                data:{
                    name:name,
                    psw:psw,
                    newPsw:newPsw
                },
                success:(res)=>{
                    console.log(res);
                }
            });
        });
    </script>
</body>
</html>

index.js

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

// post中间件
app.use(express.urlencoded({extended:true}));

//引入路由
const router=require('./router');
// 使用路由
app.use('/',router);

app.listen(3000,()=>{
    console.log(3000);
})

router.js

// 配置路由文件
const express=require('express');
const router=express.Router();

// 引入数据库
const sqlQuery=require('./mysql');

// 配置全局资源共享==================================
router.all("*", function (req, res, next) {
    //设置允许跨域的域名,*代表允许任意域名跨域
    res.header("Access-Control-Allow-Origin", "*");
    //允许的header类型
    res.header("Access-Control-Allow-Headers", "content-type");
    //跨域允许的请求方式 
    res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS");
    if (req.method.toLowerCase() == 'options')
        res.send(200); //让options尝试请求快速结束
    else
        next();
})

// 首页
router.get('/',(req,res)=>{
    res.send('路由首页,测试。');
})

// 1.查看所有数据
router.get('/list',(req,res)=>{
    let sql='select * from info';
    sqlQuery(sql,(result)=>{
        res.send(result);
    });
});

// 2.登录接口
router.post('/login',(req,res)=>{
    let name=req.body.name;
    let psw=req.body.psw;
    // console.log(name,psw);
    // 查询是否有该账号
    let sql=`select * from info where name="${name}"`;
    sqlQuery(sql,(result)=>{
        if(result.length>0){//有该账户
            if(result[0].password==psw){
                res.send('登录成功');
            }else{
                res.send('账号或密码错误!');
            }
        }else{
            res.send('无该账户,请注册!');
        }
    });
})

// 3.注册
router.post('/register',(req,res)=>{
    let name=req.body.name;
    let psw=req.body.psw;
    // 查询是否有该账号
    let sql=`select name from info where name="${name}"`;
    sqlQuery(sql,(result)=>{
        if(result.length>0){//有该账户
            res.send('该账户名已被注册');
        }else{
            let sql=`insert into info(name,password) values("${name}","${psw}")`;
            sqlQuery(sql,(result)=>{
                if(result.affectedRows>0){
                    res.send('注册成功!');
                }else{
                    res.send('注册失败!');
                }
            });
        }
    });
})

// 4.修改密码
router.post('/alter',(req,res)=>{
    let name=req.body.name;
    let psw=req.body.psw;
    let newPsw=req.body.newPsw;
    // 查询是否有该账号
    let sql=`select * from info where name="${name}" and password="${psw}"`;
    sqlQuery(sql,(result)=>{
        if(result.length>0){//有该账户且密码正确
            let sql=`update info set password='${newPsw}' where name='${name}'`;
            sqlQuery(sql,(result)=>{
                if(result.affectedRows>0){
                    res.send('修改成功!');
                }else{
                    res.send('修改失败!');
                }
            });
        }else{
            res.send('无该账号!或原账号密码错误!')
        }
    });
})

// 暴露
module.exports=router;

config.js

module.exports={
    mysqlInfo:{
        host:'localhost',
        user:'root',
        password:'123',
        database:'php_test'
    }
}

mysql.js

// 数据库文件
const mysql=require('mysql');
// 引入配置文件
const config=require('./config');
const connect=mysql.createConnection(config.mysqlInfo);

// 封装执行函数
function sqlQuery(sql,callback){
    connect.query(sql,(err,result)=>{
        if(err){
            console.log('数据库执行失败');
            return;
        }
        callback(result);
    })
}
//暴露
module.exports=sqlQuery;

实现页

posted @ 2021-07-25 11:19  青柠i  阅读(121)  评论(0编辑  收藏  举报