• node.js基础


    node.js基础

    1. nodejs是运行环境。
    2. npm是包管理工具。
    3. node采用模块化,所谓模块化,每个node.js为一个模块。

    commomJs模块化的规范

    1. 每个模块都有自己的作用域
    2. 在自己的模块中,module变量代表自身
    3. module.exports提供对外的接口

    require语法

    1. /代表绝对路径,./代表相对路径
    2. 默认后缀为:js json node 且优先级为js>json>node 如果省略后缀的话,则会先查找js查找到之后就引入js,不再查找
      例如: require(‘http’)表示导入http包

    global 全局对象

    所有的module都可以引用。

    cnpm

    将xxx模块下载到当前目录下

    cnpm install xxx  
    
    • 1

    简写

    cnpm i xxx
    
    • 1

    全局

    cnpm install xxx -g
    
    • 1

    局部 生产环境

    cnpm install xxx -S
    
    • 1

    局部 开发环境

    cnpm install xxx -D
    
    • 1

    package.json 项目的描述文件

    在node项目中,可以没有node_modules,但是必须要有package.json,有package.json的情况下,可以cd到package.json所在目录,然后在命令行使用

    cnpm i
    
    • 1

    npm上传包

    上传包到npm网站,即https://www.npmjs.com/
    上传需要切换到需要上传的包的目录内,先登录

    npm login
    
    • 1

    然后使用

    npm publish 
    
    • 1

    获取请求的url

    利用node进行后端开发,所以需要获取请求的url。
    想要实现点击url后端获取到前端的url是什么的功能。

    前端界面示例如下

    
    
    
        Document
    
    
        
    进入详情页
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    后端监控程序如下:

    const http = require("http")
    const url = require("url")
    
    const server = http.createServer((req,res) => {
        const reqUrl = req.url;
        const queryUrl = url.parse(reqUrl,true).query;
        
        console.log(queryUrl);
        res.end();
    })
    
    server.listen(8080);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    获取表单的参数get

    • get方法为地址传参

    前端界面如下:

    
    
    
        Document
    
    
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    后端代码如下:

    const http = require("http")
    const url = require("url")
    
    const server = http.createServer((req,res) => {
        // 解决页面上显示的中文乱码
        res.writeHead(200,{"Content-Type":"text/html;charset=utf8"})
        
        const reqUrl = req.url;
        const queryUrl = url.parse(reqUrl,true).query;
        console.log(queryUrl.userName,queryUrl.userPassword)
        console.log(queryUrl);
        res.end("用户名:" +queryUrl.userName );
    })
    
    server.listen(8080);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    获取表单的参数 post

    • post方法为事件传参

    前端界面还采用get的界面,仅仅是 method方法更改为 post

    
    
    
        Document
    
    
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    post解析参数方法如下:

    const http = require("http")
    const quertstring = require('querystring')
    
    const server = http.createServer((req,res) => {
        // 解决页面上显示的中文乱码
        // res.writeHead(200,{"Content-Type":"text/html;charset=utf8"})
        
        let postVal = "";
        req.on("data",(chunk)=>{
            postVal += chunk;
        })
    
        req.on("end",()=>{
            console.log(quertstring.parse(postVal))
            res.end()
        })
    
    
    })
    
    server.listen(8080);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    连接数据库

    1. 先切换到创建后台工程的文件夹中,使用下面的指令安装mysql相关依赖包
    npm install mysql
    
    • 1
    1. 在server.js中连接数据库
    const mysql = require("mysql")
    const connection = mysql.createConnection({
        host:"localhost",
        user:"root",
        password:"root",
        database:"demo",
        port:"3306"
    })
    
    connection.connect();
    connection.query('select * from ad_channellist',(err,results,fields)=>{
        if(err) throw err;
        console.log(results);
    })
    connection.end();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    登录小案例

    此案例首先获取登录的post参数,再根据登录的post参数到数据库进行查询,查询到对应的数据返回登录成功,否则返回登录失败。

    const mysql = require("mysql")
    const http = require("http")
    const quertstring = require('querystring')
    
    const server = http.createServer((req,res) => {
        let postVal = "";
    
        req.on("data",(chunk) =>{
            postVal = postVal + chunk;
        })
    
        req.on("end",()=>{
            let formarl = quertstring.parse(postVal);
            let name = formarl.userName;
            let password = formarl.userPwd;
            
    
            const connection = mysql.createConnection({
                host:"localhost",
                user:"root",
                password:"root",
                database:"demo",
                port:3306
            })
            
            connection.connect();
    
            connection.query('select * from ad_channellist where channelName=?',[name],(err,results,fields)=>{
                if(err) throw err;
                console.log(results);
                if(results.length > 0){
                    res.writeHead(200,{"Content-Type":"text/html;charset=utf8"});
                    res.write("登录成功");
                    res.end();
                }
                
            })
            connection.end();
        })
    })
    
    server.listen(8080);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    登录注册小案例

    前端界面如下:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset='utf-8'>
        <meta http-equiv='X-UA-Compatible' content='IE=edge'>
        <title>登录界面</title>
        <meta name='viewport' content='width=device-width, initial-scale=1'>
        <link rel='stylesheet' type='text/css' media='screen' href='main.css'>
        <script src='main.js'></script>
    </head>
    <body>
        <form method="post" action="http://localhost:8080/login">
            <input type="text" name="userName">
            <input type="password" name="userPwd">
            <input type="submit" value="登录">
        </form>
        <form method="post" action="http://localhost:8080/register">
            <input type="text" name="userName">
            <input type="password" name="userPwd">
            <input type="submit" value="注册">
        </form>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    实现的过程中,可以根据req.url对前端请求的网址进行区分。每次前端进行请求,都是额外请求一次"/favicon.ico"图标,所以需要对其进行过滤。

    node后端实现如下:

    const mysql = require("mysql")
    const http = require("http")
    const quertstring = require('querystring')
    
    const server = http.createServer((req,res) => {
        let postVal = "";
        req.on("data",(chunk) =>{
            postVal = postVal + chunk;
        })
    
        console.log(req.url);
        if(req.url != "/favicon.ico"){
            if(req.url == "/login"){
            
            req.on("end",()=>{
                let formarl = quertstring.parse(postVal);
                let name = formarl.userName;
                let password = formarl.userPwd;
    
                const connection = mysql.createConnection({
                    host:"localhost",
                    user:"root",
                    password:"root",
                    database:"demo",
                    port:3306
                })
                
                connection.connect();
    
                connection.query('select * from ad_channellist where channelName=?',[name],(err,results,fields)=>{
                    if(err) throw err;
                    console.log(results);
                    if(results.length > 0){
                        res.writeHead(200,{"Content-Type":"text/html;charset=utf8"});
                        res.write("登录成功");
                        res.end();
                    }
                    
                })
                connection.end();
            })
        }else{
            if(req.url == "/register"){
            
                req.on("end",()=>{
                    let formarl = quertstring.parse(postVal);
                    let name = formarl.userName;
                    let password = formarl.userPwd;
    
                    const connection = mysql.createConnection({
                        host:"localhost",
                        user:"root",
                        password:"root",
                        database:"demo",
                        port:3306
                    })
                    
                    connection.connect();
        
                    connection.query('insert into ad_channellist value (?,?,?,?,?,?)',[0,123,name,132,"132",""],(err,results,fields)=>{
                        if(err) throw err;
      
                        res.writeHead(200,{"Content-Type":"text/html;charset=utf8"});
                        res.write("添加成功");
                        res.end();
                        
                    })
                    connection.end();
                })
            }
        }
        
        }
    
        
    })
    
    server.listen(8080);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    express框架学习与理解

    ---------bin 程序的入口文件
    ------------------------------www 改文件声明端口号,导入APP
    ---------node_modules node的依赖库
    ---------public 相关资源
    ---------routes 路由中声明了网址路径
    ------------------index.js 路由1中声明了网址路径,可以声明多个网址路径。
    ------------------route1 路由1中声明了网址路径,可以声明多个网址路径。
    ---------views 路由中如果是渲染网页,可以将渲染的程序放在views中。
    ---------app app与routes关联

    模板语法:

    在routes目录下的index.js中创建一个index.js对象

    router.get('/', function(req, res, next) {
      res.render('index', {
        title: 'Express' ,
        msg: 'hello world'
      });
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    index.js对象渲染views中的index.ejs对象,则index.ejs对象中就可以引入

    
    
      
        <%= title %>
        
      
      
        

    <%= title %>

    Welcome to <%= title %>

    <%= msg %>

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    index.js对象修改

    修改index中的路径:为/admin

    router.get('/admin', function(req, res, next) {
      res.render('index', {
        title: 'Express' ,
        msg: 'hello world'
      });
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    index.ejs中文件为:

    
    
      
        <%= title %>
        
      
      
        
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    最终目标想要实现登录,所以需要使用到数据库,使用到数据库时,程序中需要引入数据库,并且post的action中,需要声明点击后的动作,以及button改成submit,text中声明name

    
    
      
        <%= title %>
        
      
      
        
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    文件操作

    文件夹异步增删改查

        // 创建文件夹
        fs.mkdir("logs",(err)=>{
            if (err) throw err
            console.log("文件夹创建成功!")
        })
    
        // 删除文件夹
        fs.rmdir("log1",(err)=>{
            if (err) throw err
            console.log("done!")
        })
    
        // 修改文件夹
        fs.rename('./logs','./log1 ',()=>{
            console.log("文件夹名称修改成功!")
        })
    
        // 查看文件夹
        fs.readdir('./logs',(err,result)=>{
            console.log("error:"+ err + " result:" + result)
        })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    文件异步增删改查

        // 创建文件写,要求必须有上级文件
        fs.writeFile('./logs/log1.log', 'hello \n world', (err) => {
            if (err) throw err
            console.log('done..')
        })
    
        // 添加内容
        fs.appendFile('./logs/log1.log', '!!!!', (err) => {
            if (err) throw err
            console.log('done..')
        })
    
        // 删除文件
        fs.unlink('./logs/log1.log', (err) => {
            if (err) throw err
            console.log('done..')
        })
        
        // 读取文件、读取出的是Buffer,因此需要对声明编码方式或者是使用toString
        fs.readFile('./logs/log1.log','utf-8', (err,content) => {
            if (err) throw err
            console.log('content:' + content)
        })
        fs.readFile('./logs/log1.log', (err,content) => {
            if (err) throw err
            console.log('content:' + content.toString())
        })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    流处理—读写

    当文件比较大时,比如说几十M到几百M,此时不能将文件直接写入内存中,需要用到流来进行处理。
    使用流处理的时候分为读流与写流。

    读流如下

        const readStream = fs.createReadStream("./log/file0.log","utf-8")
        readStream.on("data", (chunk)=>{
            console.log("chunk-",chunk)
        })
    
        readStream.on("end", ()=>{
            console.log("end")
        })
    
        readStream.on("error", (err)=>{
            console.log(err)
        })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    写流如下:
    写入hello.txt文件中,写入的标志w,编码utf-8

        let ws = fs.createWriteStream("hello.txt", {flags: "w", encoding: "utf-8"});
        // 文件打开事件
        ws.on('open', function () {
            console.log("文件打开")
        })
        // 文件关闭事件
        ws.on("close", function () {
            console.log("文件写入完成,关闭")
        })
    
        ws.write("hello world 1!",function (err){
            if (err){
                console.log(err)
            }else{
                console.log("内容流入完成1")
            }
        })
    
        ws.write("hello world!2",function (err){
            if (err){
                console.log(err)
            }else{
                console.log("内容流入完成2")
            }
        })
    
        ws.write("hello world3!",function (err){
            if (err){
                console.log(err)
            }else{
                console.log("内容流入完成3")
            }
        })
    
        ws.write("hello world4!",function (err){
            if (err){
                console.log(err)
            }else{
                console.log("内容流入完成4")
            }
        })
        ws.end(function (){
            console.log("文件流入关闭")
        })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    读流如下:
    单次读取时,默认的大小为65536

    // 创建读取流  语法 fs.createReadStream(路径,配置项(可选))
        let rs = fs.createReadStream('hello.txt', {flags: 'r', encoding: "utf-8"});
    
        rs.on('open',function (){
            console.log("文件读取打开")
        })
    
        rs.on('close',function (){
            console.log("读取流结束")
        })
    
        // 每一批数据流入完成
        rs.on('data',function (chunk){
            console.log("读取的文件已打开")
            console.log(chunk)
        })
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    读取流快速写入到写入流
    可以将读取信息直接插入到写入文件中

    
        // 创建读取流  语法 fs.createReadStream(路径,配置项(可选))
        let rs = fs.createReadStream('hello.txt', {flags: 'r', encoding: "utf-8"});
    
        let ws = fs.createWriteStream('a.txt', {flags: 'w', encoding: "utf-8"});
    
        rs.on('open',function (){
            console.log("文件读取打开")
        })
    
        rs.on('close',function (){
            console.log("读取流结束")
        })
    
        // 每一批数据流入完成
        rs.on('data',function (chunk){
            console.log("读取的文件已打开")
            console.log(chunk)
        })
    
        rs.pipe(ws);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    node语法

    node遵循错误优先的准则, 回调的第一个参数总是err。

    async与await

    async表示异步的意思。
    await表示等待的意思,等待的是一个值或者是Promise对象。

    new RegExp(“regexp”,“g”)

    g 修饰符用于执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。

    node执行流程

    1. node存在一个调用栈,当node后台收到网页发送请求后,网页请求就会进栈。
    2. 为了加快node的处理速度,一般会将进栈后的请求放入异步模块中进行处理,并且将记录回调。
    3. 异步模块中某个请求完成之后,将请求的结果发送给事件循环,事件循环再根据某个顺序将回调函数(请求结果)返回给调用栈。

    node开发原则

    1. 捕获并处理每一个错误。

    同步代码异常处理。
    try…catch…
    异步代码异常捕获。

    1. promise…catch…
    2. try…catch…
      万能的异常捕获。process.on方法,node中所有未被捕获的异常都会再此处理。
      兜底方案,不是推荐方案,因为无法向前端返回错误状态。
    process.on("uncaughtException",(err)=>{
    	console.log(err);
    })
    
    • 1
    • 2
    • 3

    Array.find()

    返回找到的第一个元素,如果没有找到返回undefined

    const array1 = [5, 12, 8, 130, 44];
    const found = array1.find(element => element === 12);
    console.log(found);
    
    • 1
    • 2
    • 3

    result:

    12
    
    • 1
  • 相关阅读:
    STM32 Debug查看const变量 在flash中存储地址
    为诚的Python学习笔记(基本语法)
    【踩坑】POST 方法的基于摘要的协商缓存实现
    Ventus(承影):基于RISC V的开源GPGPU
    视频网站接入CDN会有什么效果?
    Spring扩展接口(1):ApplicationContextInitializer
    【前端】特效开发
    【栈】736. Lisp 语法解析
    C++:map与set简析
    还不会日志异常检测?看完这篇文章就够了
  • 原文地址:https://blog.csdn.net/qq_42015021/article/details/126806693