• 前端(Node.js)(3)-- Node.js实战项目开发:“技术问答”


    1、Web 与 Node.js 相关技术介绍

    1.1、Web应用的基本组件

      web应用的三大部分

      brower(GUI)<==>webserver(business logic、data access)<==>database(data storage)

      GUI(浏览器、HTTP客户端)

      Web服务器(Node.js service)

        请求(浏览器访问网页时发送一个请求给服务器)

        业务逻辑(服务器进行处理请求)

        连接数据库(处理的过程中需要连接数据库,进行数据处理,最后将数据返回给GUI也就是浏览器,这是一个请求响应的过程)

      数据库(SQLite,LevelDB,Redis)

      GET  /yorkie HTTP/1.1

      Host:github.com

      Connection:keep-alive

      Accept:text/html,application/xhtml

      User-Agent:My iPhone

      Accept-Encoding:gzip,deflate,sdch

      (请求的方法(method))get就是个请求请求的方法有很多种,主要有get和post两种,其他还有很多

      /yorkie这部分就是请求的路径,也是一个资源的定位

      1.1这一部分标识使用的HTTP的版本

      Host:github.com这一部分表示我们要访问的域名,访问域名最后就可以转化成一个url了

      

    1.2、expressjs框架

      npm install express -g(全局安装成功,不带-g出现错误提示)

      安装成功之后这时桌面(安装完会提示安装到哪了,具体看下图:)会出现node_moudules这么一个文件夹

    [lin@vultr ~]$ sudo npm install express -g
    /usr/lib
    └─┬ express@4.16.4 
      ├─┬ accepts@1.3.5 
      │ ├─┬ mime-types@2.1.21 
      │ │ └── mime-db@1.37.0 
      │ └── negotiator@0.6.1 
      ├── array-flatten@1.1.1 
      ├─┬ body-parser@1.18.3 
      │ ├── bytes@3.0.0 
      │ ├─┬ http-errors@1.6.3 
      │ │ └── inherits@2.0.3 
      │ ├─┬ iconv-lite@0.4.23 
      │ │ └── safer-buffer@2.1.2 
      │ └── raw-body@2.3.3 
      ├── content-disposition@0.5.2 
      ├── content-type@1.0.4 
      ├── cookie@0.3.1 
      ├── cookie-signature@1.0.6 
      ├─┬ debug@2.6.9 
      │ └── ms@2.0.0 
      ├── depd@1.1.2 
      ├── encodeurl@1.0.2 
      ├── escape-html@1.0.3 
      ├── etag@1.8.1 
      ├─┬ finalhandler@1.1.1 
      │ └── unpipe@1.0.0 
      ├── fresh@0.5.2 
      ├── merge-descriptors@1.0.1 
      ├── methods@1.1.2 
      ├─┬ on-finished@2.3.0 
      │ └── ee-first@1.1.1 
      ├── parseurl@1.3.2 
      ├── path-to-regexp@0.1.7 
      ├─┬ proxy-addr@2.0.4 
      │ ├── forwarded@0.1.2 
      │ └── ipaddr.js@1.8.0 
      ├── qs@6.5.2 
      ├── range-parser@1.2.0 
      ├── safe-buffer@5.1.2 
      ├─┬ send@0.16.2 
      │ ├── destroy@1.0.4 
      │ └── mime@1.4.1 
      ├── serve-static@1.13.2 
      ├── setprototypeof@1.1.0 
      ├── statuses@1.4.0 
      ├─┬ type-is@1.6.16 
      │ └── media-typer@0.3.0 
      ├── utils-merge@1.0.1 
      └── vary@1.1.2 
    在网络服务器上的

      

    本地安装:
    npm install xxx 安装到命令行所在目录的node_module目录。
    全局安装:
    npm install xxx -g 安装到 AppDataRoaming pm ode_modules目录。

     下面一段代码简单实现在浏览器页面显示一部分内容:

    var express = require('express');
    var app = express();
    
    app.get('/jikexueyuan',function(req,res){
      res.send('hello jikexueyuan');
    });
    
    app.listen(3000);

    以下是在浏览器中显示的内容。  

    注意查看expressJS官方API文档的侧边栏的基本组件

    2、expressjs 的配置与路由

    2.1、expressjs基础

      请求和响应的数据全部放在头部是不现实的。

      get一般是从服务器拿数据,是没有{body}这种东西的

      

    //or cristring style
    
    name=hahaha
    
    name=hahaha&foo=bar&x[y]=10
    {
      name:'hahaha',
      foo:'bar',
      x: { y: 10}
    }
    
    //expressjs
    
    request_object = {
      method:&apos;POST&apos;,
      path: &apos;/hahahaha&apos;,
      headers:{
            &apos;Content-Type&apos;:&apos;application/json&apos;,
            ...
            ...
            }
      body:{}
    }
    
    request.body = JSON.parse(rawBody);
    bodyparser.urlEncoded();
    
    
    //response
    
    HTTP/1.1 200 OK
    ...
    ..
    ...
    
    //express
    status
    
    var response = {}
    response.status = function (){};
    response.status(200);
    response.status(500);
    
    response.headers['Content-Type'] = 'application/json';
    response.set('Content-Type', 'application/json');
    
    response.send([20]);
    response.json()

     

    比较重要的点:

      req.path

      req.hostname(主机名)

      req.body

      bodyParser(模组:用处:用来解析BODY的,因为body有很多编码方式(像json、cristring等等)express自己是不会自己进行解析的,bodyParser提供了两种方式

      request.body = JSON.parse(rawBody);

      bodyparser.urlEncoded();

    2.2、expressjs的初始化配置

    request

          |

    middleware 1

          |

    middleware 2

          |

    middleware 2

          |

       URL

          |

    response

      middleware: (中间件----由很多回调函数组成的东西)

        app.use

        app.get

        app.post

      request:

        req.params

        req.query

        req.body

      response:

        res.send()

        next()

    2.3、expressjs的路由

    2.4、expressjs的返回响应

    app = express()

    app.use

      body-parser:https://github.com/expressjs/body-parser

    res.send()

      plain text

      JSON

    代码示例:

    var express = require('express');
    var app = express();
    
    app.get('/plain-text', function(req, res){
        res.status(200).send('<h1>'+"hello"+`world<h1>`);
    });
    
    app.get('/category', function(req, res){
      res.status(200);
      res.json({
        python: 20, 
        nodejs: 1,
        others: 10
      }); 
    });
    
    var questions = [ 
        {   
          id:1,
          title: 't1',
          asker: 'you',
          course: 'nodejs',
          'last-reply': Date.now(),
          reply:1,
          state: 'resolved'
        },
        {
          id:2,
          title: 't2',
          asker: 'you',
          course: 'nodejs',
          'last-reply': Date.now(),
          reply: 1,
          state: 'unresolved'
        },
        {
          id:3,
          title: 't3',
          asker: 'you',
          course: 'nodejs',
          'last-reply': Date.now(),
          reply: 1,
          state: 'unresolved'
        },
        {
          id:4,
          title: 't4',
          asker: 'you',
          course: 'nodejs',
          'last-reply': Date.now(),
          reply: 1,
          state: 'unresolved'
        }
      ];
    
    app.get('/questions', function(req, res){
      res.status(200);
      res.json(questions);
    });
    
    //liebiao guolv (jia ru yi ge state)
    
    app.get('/questions/all', function(req, res){
        res.status(200);
        res.json(questions);
    });
    
    app.get('/questions/unresolved', function(req, res){
        res.status(200);
        res.json(questions.filter(function(q){
            //console.log("q : "+ q);
            //console.log("q.state : " + q.state );
            //console.log("q && q.state: " + (q && q.state));
            var ppp = q && q.state;
            //console.log(ppp);//resolved unresolved unresolved unresolved
            //if(q.state === 'unresolved')return q; //This is the same function!!!
            if(q.state ==='unresolved')return true;//This is the real function !!!
            //return q && q.state === 'unresolved';
    }));
    });
    
    app.get('/questions/resolved', function(req, res){
        res.status(200);
        res.json(questions.filter(function(q){
            return q && q.state === 'resolved';
    }));
    });
    
    app.listen(3000);

    3、expressjs 与HTML

    3.1、使用expressjs返回HTML内容

    HTML

      Content-Type:text/html(服务器要返回给客户端什么类型的数据)

      fs.createReadStream('xxx.html').pipe(res)

      res.render()

    3.2、模板渲染

    模板:

      用途:复用HTML组件,简化开发流程

      比喻:模具

    渲染/生成:

      用途:“生成”最终的HTML内容

      比喻:烤饼干

    3.3、使用app.set来设置express实例所使用的模板引擎

    ejs:http://ejs.co(模板引擎)

    使用模板引擎,需要加一个语句(想用其他的模板引擎的话,直接修改ejs这一部分)

    app.set('view engine', 'ejs')
    res.render('home.ejs', {title: 'ejs template'})

    这里出现了cannot find module 'ejs' 的问题,解决办法是在用户目录下执行以下两行命令

    npm install ejs -g  (全局安装ejs)(发现全局安装ejs之后并不起作用(这里是我忘了这是普通用户的原因了。)之后再执行下面一行命令)
                  (全局安装就是必须用root权限安装,不是root用户就用sudo ,是root就直接使用以上命令安装) npm
    install ejs  (在代码目录下再安装一次)

    安装完成功之后的情况下可以移动当前所在目录的项目了,具体原因未知。不过对我来说,可以用就行了!

    render_myprogram2.js

    var express = require('express');
    var app = express();
    
    app.set('view engine', 'ejs');
    app.set('views', __dirname + '/views');
    /*定义views的路径*/
    /*__dirname好像是个全局变量,注意这里是两个下划线*/
    app.get('/', function(req, res){
        res.render('home.ejs', {name: 'nameishahaha'});
    });
    
    app.listen(3000);

    home.ejs(views目录下的home.ejs)

    <html>
    <head>
        <title>new template</title>
    </head>
    <body>
        <p> hello hahahahahaha </p>
        <p> Hi <%= name %> </p>
    </body>
    </html>

     如何与request对象进行结合:

    render_myprogram.js

    var express = require('express');
    var app = express();
    
    app.set('view engine', 'ejs');
    app.set('views', __dirname + '/views');
    /*定义views的路径*/
    /*__dirname好像是个全局变量,注意这里是两个下划线*/
    app.get('/', function(req, res){
        res.render('home.ejs', {name: 'nameishahaha'});
    });
    
    app.get('/request/:id', function(req, res){
        var locals = {name: 'gagagagaga', 'id': req.params['id']};
        res.render('home.ejs', locals);
    });
    
    app.listen(3000);

    home.ejs(views目录下的home.ejs)

    <html>
    <head>
        <title>new template</title>
    </head>
    <body>
        <p> hello hahahahahaha </p>
        <p> Hi <%= name %> </p>
        <p> id <%= id %> </p>
    </body>
    </html>

    3.4、前后端共用模板

     在前端渲染(render)模板

    <script srv="ejs.js"></script>
    ejs.render(tmpl,data)

    复制文件ejs.min.js到根目录下的headers文件夹下

    这里老师讲的main文件没有引入,不知道原因是什么他运行着没有问题,但是我还是自己引入了main1.js

    下面是代码

    render_my_program2.js

    var express = require('/usr/lib/node_modules/express');
    //这里是真的屌,原来这里的参数是express框架的目录,恕我愚钝
    //所以这里可以通过在项目目录执行npm install express来解决呢
    var app = express();
    
    app.set('view engine', 'ejs');
    app.set('views', __dirname + '/views');
    /*定义views的路径*/
    /*__dirname好像是个全局变量,注意这里是两个下划线*/
    
    app.use(express.static(__dirname));
    //console.log(__dirname);//  /home/lin/lin_nodejs_nodes/my_project1
    
    app.get('/', function(req, res){
        res.render('home.ejs', {name: 'nameishahaha'});
    });
    
    app.get('/request/:id', function(req, res){
        var locals = {name: 'gagagagaga', 'id': req.params['id']};
        res.render('home.ejs', locals);
    });
    
    app.listen(3000);

    /views/home.ejs

    <html>
    <head>
        <title>new template</title>
    </head>
    <body>
        <p> hello hahahahahaha </p>
        <p> Hi <%= name %> </p>
        <p> id <%= id %> </p>
        <input id="new-temp-val" type="text">
        <div id="new-temp"></div>
    </body>
    
    <script type="text/javascript" src="/ejs.min.js"></script>
    <!--这里的/ejs.min.js是__dirname/ejs.min.js-->
    <script type="text/javascript">
        //alert("test_alert");
        
        var tmpl = '<p>A new template</p>';
        var newTempDiv = document.getElementById('new-temp');
        
    /*  setTimeout(function(){
            newTempDiv.innerHTML = ejs.render(tmpl);
        },2000); 
    */ //因为后面有了main.js所以这里的js代码不管用了,就注释掉可以了
    </script>
    <script type="text/javascript" src="/main_js_dir/main1.js"></script>
    <!--/指的是当前项目的工作路径的根目录,我没写/的时候报错了。-->
    </html>

    /main_js_dir/main1.js

    //alert("test_alert");//alert好像在只有声明了是text/javasceipt类型才会管用,在这里不管用
    console.log("????");
    var newTemp = document.getElementById('new-temp');
    
    
    setInterval(function(){
        var tmpl = '<p>the value is <%= val1 %></p>';
        val1 = document.getElementById('new-temp-val').value || null;
        newTemp.innerHTML = ejs.render(tmpl);
    },2000);

     

    4、模组化

    1、如何设计API

      不要让用户使用关键字new

      保持简洁

      不要轻易地输出接口

    2、发布到NPM

      npm publish

      生成一个package.json文件,在生成的时候他会自动地把你的一些内容给输入进去,包括你之前有node modules他会自动识别node modules里面的模组,然后将他们包含在你的package里面,这样你在别人从npm装上你的包的时候就能自动安装这些dependencys(依赖),这样比较方便的,所以npm init是比较方便的东西,等你准备发布之后,你可使用npm publish将你的包上传到npm的服务器上,然后在另外一台机器上你就可以用npm install +你的名字然后就可以将你相应的包下载到对应的node modules目录下

    3、课程总结

      express或Node.js在开发Web应用程序的基本流程

      如何在Node.js中复用代码并使用npm来分发

  • 相关阅读:
    C#
    if
    .net 5.0
    C# 未提供必须形参对应的实参
    EasyRTC报错 “[ERR] mod_local_stream.c:880 Unknown source default”排查
    EasyRTC通过公网进入会议室失败问题排查及解决
    【CF1558B】Up the Strip
    【AT Keyence2019E】Connecting Cities
    【洛谷P7470】岛屿探险
    【洛谷P6628】丁香之路
  • 原文地址:https://www.cnblogs.com/foreverlin/p/10135236.html
Copyright © 2020-2023  润新知