zoukankan      html  css  js  c++  java
  • Node.js_06 express

    一、初探

    1 express是什么

    • Express.js 框架是目前最流行的node.js后端框架之一, 相当于jQuery和js之间的关系;
    • Express 不对 Node.js 已有的特性进行二次抽象,我们只是在它之上扩展了 Web 应用所需的基本功能;
    • 功能类似的后端框架:Koa.js, egg.js, hapi.js

    2 安装

    • 进入应用目录

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

    • 安装 Express 并将其保存到依赖列表中 npm install express --save

      如果只是临时安装 Express,不想将它添加到依赖列表中,只需略去 --save 参数即可 npm install express

    3 Express 应用生成器

    通过应用生成器工具 express 可以快速创建一个应用的骨架。

    • 安装 npm install express-generator -g ,这个可以在cmd 里执行,全局安装,全局安装以后在哪儿都可以直接用了。

    常用操作: express -h -h 选项可以列出所有可用的命令行选项

    • 新建一个文件夹demos, 在该文件夹下执行 express --view=ejs demo1 设置视图模板, 这句执行完毕后,接下来怎么执行,命令行会提示
    • 安装所有依赖包 npm install
    1. 设置视图模板 express --view=ejs demo1

    2. 启动应用:

      • MacOS 或 Linux 平台: DEBUG=myapp npm start
      • Windows 平台: set DEBUG=myapp & npm start
      • 在浏览器中打开 http://localhost:3000/ 网址就可以看到这个应用了
    3. 通过 Express 应用生成器创建的应用一般都有如下目录结构:

    4.中间件

    通过app 根据路径处理 客户端传来的 get post 请求:

    // 1 引入
    const express = require('express');
    
    // 2 创建一个server
    const app = express();
    
    // 3 通过app 根据路径处理 客户端传来的 get post 请求
    app.get('/',(req,res)=>{
        res.write('<h1>there is two ways,the one is the right way ,the other way is the easy way!</h1>');
        res.end();
    });
    
    app.get('/pub',(req,res)=>{
        res.write('<p>there is a way!</p>');
        res.end();
    });
    
    // 
    app.get('/it', (req, res)=>{
        console.log(req.url);
        res.write('<h2>it</h2>');
        res.end();
    });
    
    // 4 开启监听
    app.listen(3000,()=>{
        console.log('server is running');
    });
    
    /*
    
    访问:http://localhost:3000/   ----there is two wa......
    访问: http://localhost:3000/pub ---- there is a way!  
    访问:http://localhost:3000/it?name=jack&age=12  server端打印: /it?name=jack&age=12
    
    */
    

    app.use:

    const express = require('express');
    const app = express();
    
    // 中间件
    app.use((req,res,next)=>{
        console.log(111);
        next();  // next() 后,才会继续往下面执行,否则就会卡在这里,后面的也不会执行了
    });
    
    app.use((req,res,next)=>{
        console.log(222);
        next();
    });
    
    app.use((req,res,next)=>{
        console.log(333);
        next();
    });
    
    app.get('/pub',(req,res,next)=>{
        console.log('pub file');
        next();
    });
    
    app.get('/',(req,res,next)=>{
        console.log('aaa');
        res.write('<h1>hello a</h1>');
        res.end();
    });
    
    app.listen(3000,()=>{
        console.log('server is running');
    })
    
    // 直接访问 http://localhost:3000/  打印
    /*
    server is running
    111
    222
    333
    aaa
    */
    /*
    * 访问  http://localhost:3000/pub
    *
    * server is running
    111
    222
    333
    pub file
    
    * */
    

    用中间件写日志:

    const express = require('express');
    const fs = require('fs');
    const app = express();
    
    app.use((req,res,next)=>{
        const lg =
    `
    ---------------------------
    请求方式:${req.method},
    请求路径:${req.url},
    请求时间:${new Date}
    --------------------------- 
    
    
    `
    
        // 写入文件
        fs.appendFile('log.txt',lg,(err)=>{
            if(err){
                console.log('log write failed');
            }else {
                console.log('log write success');
            }
        });
        res.end()
    
    })
    
    
    app.listen(3000,()=>{
        console.log('server is running..');
    })
    
    /*
    log.txt:
    ---------------------------
    请求方式:GET,
    请求路径:/,
    请求时间:Tue Dec 25 2017 12:52:27 GMT+0800 (GMT+08:00)
    --------------------------- 
    */
    

    5.静态资源文件夹配置

    const express = require('express');
    const fs = require('fs');
    const path = require('path');
    
    const app = express();
    
    // 配置静态资源文件夹
    app.use(express.static(path.join(__dirname,'public'))); //将public 文件夹作为静态资源文件夹
    
    app.get('/',(req,res,next)=>{
        console.log(path.join(__dirname, 'public'));
        res.end();
        next();
    });
    
    app.listen(3000, ()=>{
        console.log('server is running..');
    });
    
    /*
    * 访问 http://localhost:3000/images/1.jpg , 就可以访问到public/images/1.jpg 文件了
    * 访问 http://localhost:3000/  打印: E:hfivegd_codep8d7demosdemo1public
    * */
    

    6 模板引擎

    目录结构:

    engine.js:

    let express = require('express');
    let path = require('path');
    let app = express();
    
    // 1 指定视图所在位置
    app.set('views',path.join(__dirname,'views'));
    
    // 2. 注册模板引擎
    app.set('view engine','ejs');
    
    app.get('/',(req,res)=>{
        res.render('index',{"lists":["黄飞鸿","张择端","霍华德"]}); //这里放json的数据,开发中,将数据从数据库取出传这里即可。
    
    });
    app.listen(3000);
    

    index.ejs:

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
    <ul>
        <% for(var i=0; i<lists.length;i++){%>
        <li><%=lists[i] %></li>
        <%}%>
    </ul>
    </body>
    </html>
    

    运行结果:


    express 如何处理错误,如果处理找不到页面的情况,如下代码实现与 express帮我们生成的代码结构类似,可以帮我们更好的理解express 自动生成后成品结构。

    const express = require('express');
    const fs = require('fs');
    const app = express();
    
    app.get('/',(req,res,next)=>{
        try {
            const data = JSON.parse('{"name":}'); // 这里设置让程序报错
            console.log(data);
            res.json(data);
        }catch (e) {
            next(e);
        }
    });
    
    app.get('/a',(req,res,next)=>{
        res.end('hello,this is directory: a ');
    });
    
    /**
     * 统一处理错误,记录日志
     */
    app.use((err,req,res,next)=>{
        const err_log = `
        ----------------------
        错误名: ${err.name},
        错误消息: ${err.message}, 
        错误时间: ${new Date()}, 
        错误堆栈: ${err.stack}
        ----------------------
        `;
        fs.appendFile('./err_log.txt',err_log,(err)=>{
           res.writeHead(500,{"Content-Type": "text/html;charset=utf-8"});
           res.end('500,服务器内部错误');
        });
    });
    
    // 404
    app.use((req,res,next)=>{
        res.writeHead(404, {"Content-Type": "text/html;charset=utf-8"});
        res.end('您当前访问的页面不存在!!!!');
    });
    
    app.listen(3000,()=>{
        console.log('running..');
    });
    

    执行结果:

    1、访问 http://localhost:3000/ ,页面显示:500,服务器内部错误 ,并记录日志

    2、访问 http://localhost:3000/a ,页面显示:hello,this is directory: a

    3、访问 http://localhost:3000/b,页面显示:您当前访问的页面不存在!!!! ,并记录日志

    二、express + socket.io

    1、搭建

    全局安装过 generator 后,执行如下命令,创建项目文件

    express --view=ejs chat
    

    自动生成如下结构:

    然后,安装依赖

    cd chat
    npm install
    

    系统会提示:

    run the app:
     > SET DEBUG=chat:* & npm start
    
    

    运行它有两种方式,一种就是 执行 ``` npm start ``1

    或者,运行bin 目录下的 www.js 文件

    2、简要说明

    此处只记录简要内容,不记录详细细节

    引入路由文件:

    中间件:

    chat.js:

    3、 socket.io

    Socket.io 将 Websocket 和轮询( Polling )机制以及其它的实时通信方式封装成了通用的接口,并且在服务端实现了这些实时机制的相应代码。

    H5 的新技术 Websocket 仅仅是 Socket.io 实现实时通信的一个子集。

    中文文档参考 : https://www.w3cschool.cn/socket/

    安装:

    npm install socket.io --save
    

    使用 socket.IO 的时候,需要生成一个 实例对象;
    生成这个实例对象的依赖原生 node 已经建立好的 httpServer 对象

    客户端socket.on()监听的事件:
    connect:连接成功
    connecting:正在连接
    disconnect:断开连接
    connect_failed:连接失败
    error:错误发生,并且无法被其他事件类型所处理
    message:同服务器端message事件
    anything:同服务器端anything事件
    reconnect_failed:重连失败
    reconnect:成功重连
    reconnecting:正在重连

    当第一次连接时,事件触发顺序为:connecting->connect;

    当失去连接时,事件触发顺序为:disconnect、reconnecting(可能进行多次)、connecting、reconnec、connect。

    demo 演示:

    chat.ejs:

    <ul id="chatList">
        <li class="service"><span class="chat-msg">1</span></li>
        <li class="custom"><span class="chat-msg">111111,!</span></li>
        <li class="service"><span class="chat-msg">2</span></li>
        <li class="custom"><span class="chat-msg">2222222</span></li>
    </ul>
    
    <script src="/socket.io/socket.io.js"></script>
    <script src="/lib/js/jquery-3.3.1.js"></script>
    <script>
        // 1建立连接
        var socket = io('http://localhost:3000');
        socket.on('connect', function (data) {
            console.log(data);
            // 1.1 打开通道
            socket.emit('open...');
        });
    
        //2.监听
        socket.on('msg',function (data) {
            console.log(data);
            dealWithMsg('service',data)
        });
    
        // 3 点击发送
        $('#btn_send').on('click',function () {
            // 3.1 发送消息给服务器
            socket.emit('msg',$('#msg').val());
            // 3.2 显示到界面
            dealWithMsg('custom',$('#msg').val());
            // 3.3 清空消息
            $('#msg').val('');
        });
    
        let dealWithMsg = (claaName,data)=>{
            // 1 创建标签
            let $liDom = $("<li>");
            $liDom.attr({
                'class':claaName
            });
    
            // 创建span
            let $spanDom = $("<span>");
            $spanDom.attr({
               "class":"chat-msg"
            });
    
            $spanDom.text(data);
            $liDom.append($spanDom);
            $('#chatList').append($liDom);
    
    
            // 2. 让滚动条在最底部
            // $('#chatList')[0] 是把它从jquery 转成 js 了,这样就可以拿到scrollheight
            let scoreHeight = $('#chatList')[0].scrollHeight;
            $('#chatList').scrollTop(scoreHeight);
            console.log(scoreHeight);
        };
    
    </script>
    

    www.js:

    ...............
    // 1. 引入包
    const socketIO = require('socket.io');
    // 2. 针对 http server  生成 socket.IO  实例对象
    let io = socketIO(server);
    
    // 3.建立连接
    io.on('connection',(socket)=>{
        console.log('建立连接成功');
        // 3.1 返回消息
        socket.emit('msg','欢迎找我talk!');
    
        // 3.2 接收客户端的消息
        socket.on('msg',(data)=>{
            console.log(data);
            let msg = backMsg(data);
            socket.emit('msg',msg);
        });
    });
    
    // 4. 根据用户输入, 返回信息
    let backMsg = (data)=>{
        let msg = null;
        switch (data){
            case '在吗':
                msg =  '我在呢...';
                break;
            case '1':
                msg =  '1111';
                break;
            case '2':
                msg =  '2222!';
                break;
            case '3':
                msg =  '3333!';
                break;
            case '4':
                msg =  '44444444';
                break;
            default:
                msg = 'what are you talking about....';
        }
        return msg;
    };
    
    

  • 相关阅读:
    LeetCode 453 Minimum Moves to Equal Array Elements
    LeetCode 112 Path Sum
    LeetCode 437 Path Sum III
    LeetCode 263 Ugly Number
    Solutions and Summay for Linked List Naive and Easy Questions
    AWS–Sysops notes
    Linked List
    All About Linked List
    datatable fix error–Invalid JSON response
    [转]反编译c#的相关问题
  • 原文地址:https://www.cnblogs.com/friday69/p/10153021.html
Copyright © 2011-2022 走看看