zoukankan      html  css  js  c++  java
  • Nodejs学习笔记(六)—Node.js + Express 构建网站预备知识

    前言

      前面经过五篇Node.js的学习,基本可以开始动手构建一个网站应用了,先用这一篇了解一些构建网站的知识!

      主要是些基础的东西...

      如何去创建路由规则、如何去提交表单并接收表单项的值、如何去给密码加密、如何去提取页面公共部分(相当于用户控件和母版页)等等...

      下面就一步步开始吧^_^!...

    新建express项目并自定义路由规则

       1.首先用命令行express+ejs创建一个项目sampleEjsPre

    cd 工作目录
    express -e sampleEjsPre
    cd sampleEjsPre && npm install

      2.默认会有routes目录下会有index.js和users.js文件,这里为了不产生其它示例外的困扰,删除user.js文件

      3.打开app.js文件删除下面两行代码

    var users = require('./routes/users');
    
    ...
    
    app.use('/users', users);

      4.在app.js文件中添加如下代码

    var subform = require('./routes/subform');
    var usesession = require('./routes/usesession');
    var usecookies = require('./routes/usecookies');
    var usecrypto = require('./routes/usecrypto');            
    
    ...
    
    app.use('/subform', subform);
    app.use('/usesession', usesession);
    app.use('/usecookies', usecookies);
    app.use('/usecrypto', usecrypto);

      通过URL访问后,根据路由规则先到哪个文件,再到哪个文件的过程在上一篇文章(Nodejs学习笔记(五)--- Express安装入门与模版引擎ejs)中有说到,这里就不多说了!

      5.在routes目录下添加subform.js、usesession.js、usecookies.js、usecrypto.js文件,并在对应的js文件中添加如下代码

      subform.js

    var express = require('express');
    var router = express.Router();
    
    /* GET home page. */
    router.get('/', function(req, res) {
      res.render('subform', { title: '提交表单及接收参数示例' });
    });
    
    module.exports = router;

      usesession.js

    var express = require('express');
    var router = express.Router();
    
    /* GET home page. */
    router.get('/', function(req, res) {
      res.render('usesession', { title: '使用session示例' });
    });
    
    module.exports = router;

      usecookies.js

    var express = require('express');
    var router = express.Router();
    
    router.get('/', function(req, res) {
      res.render('usecookies', { title: '使用cookies示例' });
    });
    
    module.exports = router;

      usecrypto.js

    var express = require('express');
    var router = express.Router();
    
    router.get('/', function(req, res) {
      res.render('usecrypto', { title: '加密字符串示例' });
    });
    
    module.exports = router;

      6.在views目录下添加subform.ejs、usesession.ejs、usecookies.ejs、usecrypto.ejs文件,并在views目录下除了error.ejs外所有ejs文件中添加如下代码

    <!DOCTYPE html>
    <html>
      <head>
        <title><%= title %></title>
        <link rel='stylesheet' href='/stylesheets/style.css' />
      </head>
      <body>     
        <a href="/">首页</a>     
        <a href="/subform">如何提交表单并接收参数?</a>
        <a href="/usesession">如何使用session?</a>
        <a href="/usecookies">如何使用cookies?</a>
        <a href="/usecrypto">如何字符串加密?</a>
      </body>
    </html>

      7.在app.js中添加8000端口监听并运行

    ...
    app.listen(8000);
    ...

       运行界面如下:

      点击各链接都能正常跳转到对应的页面!这样第一步的目录就算达到了!

    如何提取页面中的公共部分?

      在上一步创建的网站中每个页面都几乎一样,现在都只有导航部分?每个页都要写?当然不是,我们可以提取出来

      1.在views目录下新建一个nav.ejs文件,并添加如下代码

    <a href="/">首页</a>     
    <a href="/subform">如何提交表单并接收参数?</a>
    <a href="/usesession">如何使用session?</a>
    <a href="/usecookies">如何使用cookies?</a>
    <a href="/usecrypto">如何字符串加密?</a>

      2.把views目录下index.ejs、subform.ejs、usesession.ejs、usecookies.ejs、usecrypto.ejs修改成如下代码

    <!DOCTYPE html>
    <html>
      <head>
        <title><%= title %></title>
        <link rel='stylesheet' href='/stylesheets/style.css' />
      </head>
      <body>     
          <% include nav %>
      </body>
    </html>

      运行页面,发现和上次运行时没有作何区别,有了这样的办法更有利于减少重复代码、也更有利于统一布局!

    <% include 文件名 %> express提供include来嵌入其它页,这和html嵌入其它页类似

    如果用过express2.0版本的会发现当时没有这个include,用的是一个模版文件layout.ejs来布局!

    如何提交表单并接收参数?

      如果要做一个网站应用,不可避免的会遇到表单的提交及获取参数的值,下面我们来看看用node.js + express怎么做

    先来构建一个表单简单模拟登录GET方式提交数据

       1.打开subform.ejs文件,修改文件代码为如下:

      

    <!DOCTYPE html>
    <html>
      <head>
        <title><%= title %></title>
        <link rel='stylesheet' href='/stylesheets/style.css' />
      </head>
      <body>     
          <% include nav %>
          
          <form>
              用户名:<input type="text" id="txtUserName" name="txtUserName" />
              密码:<input type="password" id="txtUserPwd" name="txtUserPwd" />
              <input type="submit" value="提交">
          </form>
        
      </body>
    </html>

      2.打开subform.js我们试着接收参数值并输出到控制台

      

    var express = require('express');
    var router = express.Router();
    
    router.get('/', function(req, res) {
      var 
      userName = req.query.txtUserName,
      userPwd = req.query.txtUserPwd,
      userName2 = req.param('txtUserName'),
      userPwd2 = req.param('txtUserPwd');
    
      console.log('req.query用户名:'+userName);
      console.log('req.query密码:'+userPwd);
      console.log('req.param用户名:'+userName2);
      console.log('req.param密码:'+userPwd2);
    
      res.render('subform', { title: '提交表单及接收参数示例' });
    });
    
    module.exports = router;

      3.运行,并提交表单 在浏览器中运行:http://localhost:8000/subform,输入表单项并提交,可以发现url发生了变化

      

      可以发现url中出现了我表单中输入并要提交的值!

      我们再看看控制台的输出

      

       我们完成了GET方式提交表单并接收到了值,不错^_^!(稍后在后面再去讲得到值的方式和区别)

    再来在上面的代码基础上去修改一下表单的method简单模拟登录POST方式提交数据

      1.首先修改一下subform.ejs文件中的form标签,修改为如下:

    <form method="post">
    ...
    </form>

      2.再在subform.js中添加代码,接收post提交、接收参数并输出到控制台

    ...
    
    router.post('/',function(req, res){
      var 
      userName = req.body.txtUserName,
      userPwd = req.body.txtUserPwd,
      userName2 = req.param('txtUserName'),
      userPwd2 = req.param('txtUserPwd');
    
      console.log('req.body用户名:'+userName);
      console.log('req.body密码:'+userPwd);
      console.log('req.param用户名:'+userName2);
      console.log('req.param密码:'+userPwd2);

     res.render('subform', { title: '提交表单及接收参数示例' }); }); ...

      3.运行,并提交表单 在浏览器中运行:http://localhost:8000/subform,输入表单项并提交,可以发现url不会发生变化

      

      改为post方式后,会发现不会跟get方式提交一样在url中出现了表单中输入并要提交的值!

      我们再看看控制台的输出

      

      OK,我们完成了POST提交表单并接收参数!

      再回过头看看GET和POST方式接收值,从直接效果上来看

      req.query:我用来接收GET方式提交参数

      req.body:我用来接收POST提交的参数

      req.params:两种都能接收到

      大家自行看看Express的Request部分的API:  http://expressjs.com/api.html#req.params

      这里着重解释一下req.body,Express处理这个post请求是通过中间件bodyParser,你可以看到app.js中有一块代码

    ...
    
    var bodyParser = require('body-parser');
    
    ...
    
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded());
    
    ...

      没有这个中间件Express就不知道怎么处理这个请求,通过bodyParser中间件分析 application/x-www-form-urlencoded和application/json请求,并把变量存入req.body,这种我们才能够获取到!

    如何字符串加密?

      当我们提交表单后,比如密码这些敏感信息,不做个加密处理那也太不把用户私密信息当回事了,Node.js提供了一个加密模块 Crypto http://nodejs.org/api/crypto.html

      下面我们用个示例使用一下

      1.打开usecrypto.js,修改代码为如下:

    var express = require('express');
    var router = express.Router();
    var crypto = require('crypto');
    
    /* GET home page. */
    router.get('/', function(req, res) {
      
      res.render('usecrypto', { title: '加密字符串示例' });
     
    });
    
    router.post('/',function(req, res){
      var 
      userName = req.body.txtUserName,
      userPwd = req.body.txtUserPwd;
    
      //生成口令的散列值
      var md5 = crypto.createHash('md5');   //crypto模块功能是加密并生成各种散列
      var en_upwd = md5.update(userPwd).digest('hex');
    
      console.log('加密后的密码:'+en_upwd);
      
      res.render('usecrypto', { title: '加密字符串示例' });
    });
    
    module.exports = router;

      2.打开usecrypto.ejs,修改代码为如下

    <!DOCTYPE html>
    <html>
      <head>
        <title><%= title %></title>
        <link rel='stylesheet' href='/stylesheets/style.css' />
      </head>
      <body>     
          <% include nav %>
    
          <form method="post">
              用户名:<input type="text" id="txtUserName" name="txtUserName" />
              密码:<input type="password" id="txtUserPwd" name="txtUserPwd" />
              <input type="submit" value="提交">
          </form>
      </body>
    </html>

      3.运行,输入并提交表单,查看控件台输出

      

      成功MD5方式加密!

      其中用到了createHash(algorithm)方法 ,这是利用给定的算法生成hash对象 

      Node.js提供的加密模块功能非常强大,Hash算法就提供了MD5、sha1、sha256等,根据需要去使用

      update(data, [input_encoding])方法,可以通过指定的input_encoding和传入的data数据更新hash对象,input_encoding为可选参数,没有传入则作为buffer处理 (input_encoding可为'utf-8'、'ascii'等)

      digest([encoding])方法,计算数据的hash摘要值,encoding是可选参数,不传则返回buffer (encoding可为 'hex'、'base64'等);当调用digest方法后hash对象将不可用;

    如何使用session?

      Internet通讯协议分为stateful和stateless两类,对Web开发有一定了解的应该知道,http是stateless协议,客户端发送请求到服务端建立一个连接,请求得得到响应后连接即中断,服务器端不会记录状态,因此服务器端想

      要确定是哪个客户端提交过来的请求,那就必须要借助一些东西去完成,就是session和cookies,现在我们先说说session,以及在nodejs下使用session !

      session存在于服务器端,需要cookies的协助才能完成;服务器端和客户端通过session id来建立联系(具体session和cookies怎么协作的,可以自已去补充点相关知识,这里只简单提一下,不展开了,要不然这篇文章就更杂了^_^!)

      express中可以用中间件来使用session,express-sessionhttps://github.com/expressjs/session ) 可以存在内存中,也可以存在mongodb、redis等中...

      更多中间件:https://github.com/senchalabs/connect#middleware

      下面我们通过示例看看怎么使用session  (内存方式)

      示例设计思路:使用两个页面,一个登录,两个页都判断是否有这个session,如果有,显示已登录,没有则显示一个登录按钮,点此按钮,记录session

      1.首先通过npm安装这个中间件,打开package.json文件,在dependencies节点下添加一个键值对  "express-session" : "latest" 

      "dependencies": {
        ...,
        "express-session" : "latest" 
      }

      lateset:最新的

      2. cd到项目根目录下,执行npm install

      

      3.打开app.js,添加如下代码

    var express = require('express');
    var path = require('path');
    var favicon = require('static-favicon');
    var logger = require('morgan');
    var cookieParser = require('cookie-parser');
    var bodyParser = require('body-parser');
    var session = require('express-session');
    
    ...      
    
    //这里传入了一个密钥加session id
    app.use(cookieParser('Wilson'));
    //使用靠就这个中间件 app.use(session({ secret: 'wilson'})); ...

      这些options就不解释了,通过上面中间件的链接,自已看一下

      4.我这里使用usesession和usecookies作示例,修改js和ejs如下

      

      

      usesession.ejs 和 usecookies.ejs

    <!DOCTYPE html>
    <html>
      <head>
        <title><%= title %></title>
        <link rel='stylesheet' href='/stylesheets/style.css' />
      </head>
      <body>     
          <% include nav %>
    
          <% if(locals.islogin){ %>
             用户已登录
        <% } else { %>
             <form method="post">          
                  <input type="submit" value="登录">
              </form>
        <% } %>
      </body>
    </html>

      usession.js

    var express = require('express');
    var router = express.Router();
    
    router.get('/', function(req, res) {
      
      if(req.session.islogin)
      {
           console.log('usesession:' + req.session.islogin);
         res.locals.islogin = req.session.islogin;      
      }
    
      res.render('usesession', { title: '使用session示例' });
    });
    
    router.post('/', function(req, res) {
      
      req.session.islogin = 'success';
      res.locals.islogin = req.session.islogin;
    
      res.render('usesession', { title: '使用session示例' });
    });
    
    module.exports = router;

      usecookies.js

    var express = require('express');
    var router = express.Router();
    
    router.get('/', function(req, res) {
    
      if(req.session.islogin)
      {
          console.log('usecookies:' + req.session.islogin);
        res.locals.islogin = req.session.islogin;      
      }
    
      res.render('usecookies', { title: '使用cookies示例' });
    });
    
    router.post('/', function(req, res) {
      
      req.session.islogin = 'success';
      res.locals.islogin = req.session.islogin;
    
      res.render('usecookies', { title: '使用cookies示例' });
    });
    
    module.exports = router;

      5.运行并查看

      第一次运行时,查看两个页,效果如下:

      

      

      6.点击登录按钮后,再查看这两个页

      

      

      7.关闭浏览器,再打开查看这两个页,如第5步截图效果

      session的使用成功!

      官方示例:https://github.com/visionmedia/express/blob/master/examples/session/index.js

    如何使用cookies?

      如果是登录,那常见就是“记录密码”或“自动登录”功能,这个一般用 cookies来完成

      cookies存在客户端,安全性较低,一般要存入加密后的信息;建议要设置使用过期时间或不使用时删除掉

      express也同样可以用中间件来使用:https://github.com/expressjs/cookie-parser

          老套路,通过一个示例了解一下

       示例设计思路:在上面session示例的基础上,在usecookies部分登录同时记录cookies,来自动登录

          1.在上面session示例的基础上修改一下usecookies.js

    var express = require('express');
    var router = express.Router();
    
    router.get('/', function(req, res) {
       
      if(req.cookies.islogin)
      { 
           console.log('usecookies-cookies:' + req.cookies.islogin);
           req.session.islogin = req.cookies.islogin;
      }  
      
      if(req.session.islogin)
      {
          console.log('usecookies:' + req.session.islogin);
        res.locals.islogin = req.session.islogin;      
      }
    
      res.render('usecookies', { title: '使用cookies示例' });
    });
    
    router.post('/', function(req, res) {
      
      req.session.islogin = 'success';
      res.locals.islogin = req.session.islogin;
    
      res.cookie('islogin', 'sucess', { maxAge: 60000 });
    
      res.render('usecookies', { title: '使用cookies示例' });
    });
    
    module.exports = router;

      2.运行访问 http://localhost:8000/usecookies,点击登录按钮登录成功并记录cookies

             maxAge为过期时长,毫秒为单位,我设置一分钟

      3.关闭浏览器,再次访问http://localhost:8000/usecookies ,页面显示已登录

           4.再次关闭浏览器,过一分钟再访问http://localhost:8000/usecookies,页面不再是已登录,而是显示登录按钮,表示cookies过期,不会自动登录

      cookies的使用到此也成功!

      官方示例:https://github.com/visionmedia/express/blob/master/examples/cookies/app.js    

    如何清除session和cookies?

      清除非常简单,就不用示例说明了,有兴趣自已定义个路由规则,试试

    //清除cookies
    res.clearCookie('islogin');
      
    //清除session
    req.session.destroy();

    写在之后

      本篇内容讲到的一些知识点,其实都可以单独拿一整篇去讲,本篇基本原则是为了看了之后能使用;

      要想弄清楚原理或者更多的相关知识,自已可以花点时间去了解,或者找点资料去丰富一下,当然也可以留言,在我觉得我没乱说的情况下我会尽量解答^_^!

    此系列的源代码可到http://bijian1013.iteye.com/blog/2425085下载。 

    文章来源:https://www.cnblogs.com/zhongweiv/p/nodejs_express_webapp1.html

  • 相关阅读:
    解决UITableView中Cell重用机制导致内容出错的方法总结
    Hdu 1052 Tian Ji -- The Horse Racing
    Hdu 1009 FatMouse' Trade
    hdu 2037 今年暑假不AC
    hdu 1559 最大子矩阵
    hdu 1004 Let the Balloon Rise
    Hdu 1214 圆桌会议
    Hdu 1081 To The Max
    Hdu 2845 Beans
    Hdu 2955 Robberies 0/1背包
  • 原文地址:https://www.cnblogs.com/flyingeagle/p/9192936.html
Copyright © 2011-2022 走看看