zoukankan      html  css  js  c++  java
  • express 初建项目注意事项

    一、概述

    1、新建一个项目目录

      > mkdir hello-world

    2、进入该目录,新建一个package.json文件,内容如下。

      //代码定义了项目的名称、描述、版本

    {
      "name": "hello-world",
      "description": "hello world test app",
      "version": "0.0.1",
      "private": true,
      "dependencies": {
        "express": "4.x"
      }
    }

    3、安装(modules)

      > npm install

    4、新建一个启动文件ndex.js文件

    var express = require('express');
    var app = express();
    
    app.use(express.static(__dirname + '/public'));
    
    app.listen(8080);

    5、例子:

    // routes/index.js
    
    module.exports = function (app) {
      app.get('/', function (req, res) {
        res.send('Hello world');
      });
      app.get('/customer', function(req, res){
        res.send('customer page');
      });
      app.get('/admin', function(req, res){
        res.send('admin page');
      });
    };
    // index.js
    var express = require('express');
    var app = express();
    var routes = require('./routes')(app);
    app.listen(3000);

    二、运行原理

    1、底层:http模块

      http模块生成服务器的原始代码如下: 

    var http = require("http");
    
    var app = http.createServer(function(request, response) {
      response.writeHead(200, {"Content-Type": "text/plain"});
      response.end("Hello world!");
    });
    
    app.listen(3000, "localhost");

    上面代码的关键是http模块的createServer方法,表示生成一个HTTP服务器实例。该方法接受一个回调函数,该回调函数的参数,分别为代表HTTP请求和HTTP回应的request对象和response对象。

    Express框架的核心是对http模块的再包装。上面的代码用Express改写如下:

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

     比较两段代码,可以看到它们非常接近。原来是用http.createServer方法新建一个app实例,现在则是用Express的构造方法,生成一个Epress实例。两者的回调函数都是相同的。Express框架等于在http模块之上,加了一个中间层。

    2、什么是中间件

    简单说,中间件(middleware)就是处理HTTP请求的函数。它最大的特点就是,一个中间件处理完,再传递给下一个中间件。App实例在运行过程中,会调用一系列的中间件。

    每个中间件可以从App实例,接收三个参数,依次为request对象(代表HTTP请求)、response对象(代表HTTP回应),next回调函数(代表下一个中间件)。每个中间件都可以对HTTP请求(request对象)进行加工,并且决定是否调用next方法,将request对象再传给下一个中间件。

    一个不进行任何操作、只传递request对象的中间件,就是下面这样。

    function uselessMiddleware(req, res, next) {
      next();
    }

     上面代码的next就是下一个中间件。如果它带有参数,则代表抛出一个错误,参数为错误文本。

    function uselessMiddleware(req, res, next) {
      next('出错了!');
    }

     △抛出错误以后,后面的中间件将不再执行,直到发现一个错误处理函数为止。

    3、use方法

      use是express注册中间件的方法,它返回一个函数。下面是一个连续调用两个中间件的例子

    var express = require("express");
    var http = require("http");
    
    var app = express();
    
    app.use(function(request, response, next) {
      console.log("In comes a " + request.method + " to " + request.url);
      next();
    });
    
    app.use(function(request, response) {
      response.writeHead(200, { "Content-Type": "text/plain" });
      response.end("Hello world!n");
    });
    
    http.createServer(app).listen(1337);

    上面代码使用app.use方法,注册了两个中间件。收到HTTP请求后,先调用第一个中间件,在控制台输出一行信息,然后通过next方法,将执行权传给第二个中间件,输出HTTP回应。由于第二个中间件没有调用next方法,所以request对象就不再向后传递了

    就是将第一个中间件的requet传递给第二个中间件。

    use方法内部可以对访问路径进行判断,据此就能实现简单的路由,根据不同的请求网址,返回不同的网页内容。

    var express = require("express");
    var http = require("http");
    
    var app = express();
    
    app.use(function(request, response, next) {
      if (request.url == "/") {
        response.writeHead(200, { "Content-Type": "text/plain" });
        response.end("Welcome to the homepage!n");
      } else {
        next();
      }
    });
    
    app.use(function(request, response, next) {
      if (request.url == "/about") {
        response.writeHead(200, { "Content-Type": "text/plain" });
      } else {
        next();
      }
    });
    
    app.use(function(request, response) {
      response.writeHead(404, { "Content-Type": "text/plain" });
      response.end("404 error!n");
    });
    
    http.createServer(app).listen(1337);

    三、搭建HTTPs服务器

    var fs = require('fs');
    var options = {
      key: fs.readFileSync('E:/ssl/myserver.key'),
      cert: fs.readFileSync('E:/ssl/myserver.crt'),
      passphrase: '1234'
    };
    
    var https = require('https');
    var express = require('express');
    var app = express();
    
    app.get('/', function(req, res){
      res.send('Hello World Expressjs');
    });
    
    var server = https.createServer(options, app);
    server.listen(8084);
    console.log('Server is running on port 8084');

    四、静态网页模板

    在项目目录之中,建立一个子目录views,用于存放网页模板。

    假定这个项目有三个路径:根路径(/)、自我介绍(/about)和文章(/article)。那么,app.js可以这样写:

    var express = require('express');
    var app = express();

    app.get('/', function (req, res) {
    res.sendFile(__dirname + '/views/index.html');
    });

    app.get('/about', (req, res) => {
    res.sendFile(__dirname + '/views/about.html');
    });

    app.get('/article', (req, res) => {
    res.sendFile(__dirname + '/views/article.html');
    });

    app.listen(3000);



    上面代码表示,三个路径分别对应views目录中的三个模板:index.html、about.html和article.html。另外,向服务器发送信息的方法,从send变成了sendfile,后者专门用于发送文件。

    5、动态网页模板

    1、安装引擎

    Express支持多种模板引擎,这里采用Handlebars模板引擎的服务器端版本hbs模板引擎。

    先安装hbs。(npm install hbs --save-dev

    上面代码将hbs模块,安装在项目目录的子目录node_modules之中。save-dev参数表示,将依赖关系写入package.json文件。安装以后的package.json文件变成下面这样:

    // package.json文件

    {
    "name": "demo",
    "description": "My First Express App",
    "version": "0.0.1",
    "dependencies": {
    "express": "3.x"
    },
    "devDependencies": {
    "hbs": "~2.3.1"
    }
    }



    安装模板引擎之后,就要改写app.js。
    // app.js文件

    var express = require('express');
    var app = express();

    // 加载hbs模块
    var hbs = require('hbs');

    // 指定模板文件的后缀名为html
    app.set('view engine', 'html');

    // 运行hbs模块
    app.engine('html', hbs.__express);

    app.get('/', function (req, res){
    res.render('index');
    });

    app.get('/about', function(req, res) {
    res.render('about');
    });

    app.get('/article', function(req, res) {
    res.render('article');
    });

    上面代码改用render方法,对网页模板进行渲染。render方法的参数就是模板的文件名,默认放在子目录views之中,后缀名已经在前面指定为html,这里可以省略。所以,res.render(‘index’) 就是指,把子目录views下面的index.html文件,交给模板引擎hbs渲染。

    5.2、新建数据脚本

    渲染是指将数据代入模板的过程。实际运用中,数据都是保存在数据库之中的,这里为了简化问题,假定数据保存在一个脚本文件中。

    在项目目录中,新建一个文件blog.js,用于存放数据。blog.js的写法符合CommonJS规范,使得它可以被require语句加载。

    // blog.js文件

    var entries = [
    {"id":1, "title":"第一篇", "body":"正文", "published":"6/2/2013"},
    {"id":2, "title":"第二篇", "body":"正文", "published":"6/3/2013"},
    {"id":3, "title":"第三篇", "body":"正文", "published":"6/4/2013"},
    {"id":4, "title":"第四篇", "body":"正文", "published":"6/5/2013"},
    {"id":5, "title":"第五篇", "body":"正文", "published":"6/10/2013"},
    {"id":6, "title":"第六篇", "body":"正文", "published":"6/12/2013"}
    ];

    exports.getBlogEntries = function (){
    return entries;
    }

    exports.getBlogEntry = function (id){
    for(var i=0; i < entries.length; i++){
    if(entries[i].id == id) return entries[i];
    }
    }


    5.3、新建网页模板

    接着,新建模板文件index.html。

    <!-- views/index.html文件 -->

    <h1>文章列表</h1>

    {{#each entries}}
    <p>
    <a href="/article/{{id}}">{{title}}</a><br/>
    Published: {{published}}
    </p>
    {{/each}}



    模板文件about.html。

    <!-- views/about.html文件 -->

    <h1>自我介绍</h1>

    <p>正文</p>


    模板文件article.html。

    <!-- views/article.html文件 -->

    <h1>{{blog.title}}</h1>
    Published: {{blog.published}}

    <p/>

    {{blog.body}}


    可以看到,上面三个模板文件都只有网页主体。因为网页布局是共享的,所以布局的部分可以单独新建一个文件layout.html。

    <!-- views/layout.html文件 -->

    <html>

    <head>
    <title>{{title}}</title>
    </head>

    <body>

    {{{body}}}

    <footer>
    <p>
    <a href="/">首页</a> - <a href="/about">自我介绍</a>
    </p>
    </footer>

    </body>
    </html>


    5.4、渲染模板

    最后,改写app.js文件。

    // app.js文件

    var express = require('express');
    var app = express();
    var bodyParser = require('body-parser')
    var hbs = require('hbs');

    // 加载数据模块
    var blogEngine = require('./blog');

    app.set('view engine', 'html');
    app.engine('html', hbs.__express);
    app.use(bodyParser.json());

    app.get('/', function(req, res) {
    res.render('index',{title:"最近文章", entries:blogEngine.getBlogEntries()});
    });

    app.get('/about', function(req, res) {
    res.render('about', {title:"自我介绍"});
    });

    app.get('/article/:id', function(req, res) {
    var entry = blogEngine.getBlogEntry(req.params.id);
    res.render('article',{title:entry.title, blog:entry});
    });

    app.listen(3000);



    注:

    Node中的核心模块分两类:一类是自带的核心模块,如http、tcp等,第二类是第三方核心模块,express就是与http对应的第三方核心模块,用于处理http请求。express在3.0版本中自带有很多中间件,但是在express 4.0以后,就将除static(静态文件处理)以外的其他中间件分离出来了;在4.0以后需要使用中间件时,就需要单独安装好相应的中间件以后调用,以下3.0与4.0中间件的中间件区别(3.0是内置中间件属性名,4.0是需要安装的中间件名称):

    
    
    
    
    

    Express 3.0 Name

    Express 4.0 Name

    bodyParser

    body-parser

    compress

    compression

    cookieSession

    cookie-session

    logger

    morgan

    cookieParser

    cookie-parser

    session

    express-session

    favicon

    static-favicon

    response-time

    response-time

    error-handler

    errorhandler

    method-override

    method-override

    timeout

    connect-timeout

    vhost

    vhost

    csrf

    csurf



    上面代码中的render方法,现在加入了第二个参数,表示模板变量绑定的数据。

    现在重启node服务器,然后访问http://127.0.0.1:3000。

    http://blog.csdn.net/ganxunzou/article/details/42918015

  • 相关阅读:
    Constants and Variables
    随想
    C#基础篇之语言和框架介绍
    Python基础19 实例方法 类方法 静态方法 私有变量 私有方法 属性
    Python基础18 实例变量 类变量 构造方法
    Python基础17 嵌套函数 函数类型和Lambda表达式 三大基础函数 filter() map() reduce()
    Python基础16 函数返回值 作用区域 生成器
    Python基础11 List插入,删除,替换和其他常用方法 insert() remove() pop() reverse() copy() clear() index() count()
    Python基础15 函数的定义 使用关键字参数调用 参数默认值 可变参数
    Python基础14 字典的创建修改访问和遍历 popitem() keys() values() items()
  • 原文地址:https://www.cnblogs.com/pyj63/p/8087196.html
Copyright © 2011-2022 走看看