express框架笔记

1、Express介绍

官网: http://www.expressjs.com.cn/
在这里插入图片描述

2、基础使用

1安装

首先假定你已经安装了 Node.js,接下来为你的应用创建一个目录,然后进入此目录并将其作为当前工作目录。

$ mkdir myapp
$ cd myapp

通过 npm init 命令为你的应用创建一个 package.json 文件。 欲了解 package.json 是如何起作用的,请参考 Specifics of npm’s package.json handling.
$ npm init
此命令将要求你输入几个参数,例如此应用的名称和版本。 你可以直接按“回车”键接受大部分默认设置即可,
接下来在 myapp 目录下安装 Express 并将其保存到依赖列表中。如下:
$ npm install express --save

2启动服务响应Helloword

var express = require("express");
var db = require("./db");

var app = express();

/**
 *   http://192.168.40.114:8081/hello
 */
app.get("/hello",function(req,res){
    res.send("hello"); //响应内容
});

/**
 * 启动web服务监听8081端口
 */
app.listen(8081,function(){
    console.log("服务端启动, http://192.168.40.114:8081");
});

3、Route路由定义格式

app.METHOD(PATH, HANDLER)
说明
• app 是express的一个实例instance
• METHOD 是 HTTP request method, in lowercase. 如GET, POST…
• PATH 是服务器请求地址路径
• HANDLER 路由匹配时执行的函数.

4、路由分类

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

// 路由:字符串类型
app.get('/book', function(req, res, next){
    res.send('book');
});

// 路由:字符串模式
app.get('/user/*man', function(req, res, next){
    res.send('user');  // 比如: /user/man, /user/woman
});

5、使用示例

Post请求处理

 var express = require("express");
var db = require("./db");

var app = express();

//get请求方法, 
//find请求url地址 
app.get("/find",function(req,res){
    res.send("find get >>>>>");  //响应内容
});

//post请求方法, 
//find请求url地址 
app.post("/find",function(req,res){
    res.send("find post >>>>>"); //响应内容
});

/**
 * 启动web服务监听8081端口
 */
app.listen(8081,function(){
    console.log("服务端启动, http://192.168.40.114:8081");
});

响应数据库查询数据
db.js 模块

 var mysql = require("mysql");

function query(sql,parmeters, callFunction) {
    //创建数据库连接对象
    var connection = mysql.createConnection(
        {
            host: "192.168.40.114",
            user: "test",
            password: "b123",
            database: "ex1db"
        }
    );

    connection.connect(); //打开数据库连接

    connection.query(sql,parmeters,callFunction); //执行sql

    connection.end(); //关闭数据连接
}

exports.query = query;
//module.exports = query;

app.js 模块

 var express = require("express");
var db = require("./db");

var app = express();

app.get("/find",function(req,res){
    var sql = "SELECT * FROM department";
    db.query(sql,function(err,data){
        if(err){
            console.log("查询数据出错");
            return;
        }
        var datajson = JSON.stringify(data);
        res.send(datajson);

    });
});

/**
 * 启动web服务监听8081端口
 */
app.listen(8081,function(){
    console.log("服务端启动, http://192.168.40.114:8081");
});

6、路由拆分

当你用的应用越来越复杂,不可避免的,路由规则也会越来越复杂。这个时候,对路由进行拆分是个不错的选择。
我们分别看下两段代码,路由拆分的好处就直观的体现出来了。
路由拆分前

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

app.get('/user/list', function(req, res, next){
    res.send('/list');
});

app.get('/user/detail', function(req, res, next){
    res.send('/detail');
});

app.listen(3000);

这样的代码会带来什么问题呢?无论是新增还是修改路由,都要带着/user前缀,这对于代码的可维护性来说是大忌。这对小应用来说问题不大,但应用复杂度一上来就会是个噩梦。
路由拆分后
可以看到,通过express.Router()进行了路由拆分,新增、修改路由都变得极为便利。

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

var user = express.Router();

user.get('/list', function(req, res, next){
    res.send('/list');
});

user.get('/detail', function(req, res, next){
    res.send('/detail');
});

app.use('/user', user); // mini app,通常做应用拆分

app.listen(3000);

7、body-parser express中间件使用

body-parser是非常常用的一个express中间件,作用是对http请求体进行解析。使用非常简单,以下两行代码已经覆盖了大部分的使用场景。

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));  //extended: false 表是只支持string|arrya类型,为true表示支持所有类型
1.入门基础

在正式讲解前,我们先来看一个POST请求的报文,如下所示。

POST /test HTTP/1.1
Host: 127.0.0.1:3000
Content-Type: application/x-www-form-urlencoded; charset=utf8
Content-Encoding: gzip

name=helloword&password=123

其中需要我们注意的有Content-Type、Content-Encoding以及报文主体:
• Content-Type:请求报文主体的类型、编码。常见的类型有text/plain、application/json、application/x-www-form-urlencoded。常见的编码有utf8、gbk等。
• Content-Encoding:声明报文主体的压缩格式,常见的取值有gzip、deflate、identity。
• 报文主体:这里是个普通的文本字符串hello。

2.body-parser主要做了什么

body-parser实现的要点如下:

  1. 处理不同类型的请求体:比如text、json、urlencoded等,对应的报文主体的格式�不同。
  2. 处理不同的编码:比如utf8、gbk等。
  3. 处理不同的压缩类型:比如gzip、deflare等。
  4. 其他边界、异常的处理。
3.处理不同类型请求体
var express = require("express");
var bodyParser = require("body-parser");

var app = express(); //创建一个express对象实例

app.use(bodyParser.json()); //解析json类型文本 content-type:application/json
app.use(bodyParser.urlencoded({extended:false})); //解析 名称值对类型文本 content-type:application/x-www-form-urlencoded

app.post("/login.do",function(req,res){
    var body = req.body;  //请求正文
    console.log(body);
    res.send(body);
});

app.get("/login.do",function(req,res){
    var query = req.query;  //请求正文
    console.log(query);
    res.send(query);
});

app.listen(8080,function(){
    console.log("启动服务器成功! http://192.168.40.114:8080");
})
4.body-parser模块使用步骤
 第一步: 安装body-parser模块
                 npm  install body-parser
          第二步: 获取模块,创建解析器
               var bodyParser = require('body-parser') //获取模块
                var jsonParser = bodyParser.json();  // 创建 application/json 解析    如: {名称1:值1,名称2:值2}
                var urlencodedParser = bodyParser.urlencoded({ extended: false });// 创建 application/x-www-form-urlencoded 解析  如: 名称1=值1&名称2=值2
           第三步: body-parser与exprerss web框架整合
                app.use(jsonParser);
                app.use(urlencodedParser);
           第四步: 获取参数值
               1. get请求
                   值1 = req.query.名称1
               2. post请求
                  值1 = req.body.名称1


8、利用 Express 托管静态文件

为了提供诸如图像、CSS 文件和 JavaScript 文件之类的静态文件,请使用 Express 中的 express.static 内置中间件函数。
此函数特征如下:
express.static(root, [options])
The root argument specifies the root directory from which to serve static assets. For more information on the options argument, see express.static.
例如,通过如下代码就可以将 public 目录下的图片、CSS 文件、JavaScript 文件对外开放访问了:
app.use(express.static('public'))
现在,你就可以访问 public 目录中的所有文件了:

http://localhost:3000/images/kitten.jpg
http://localhost:3000/css/style.css
http://localhost:3000/js/app.js
http://localhost:3000/images/bg.png
http://localhost:3000/hello.html

Express 在静态目录查找文件,因此,存放静态文件的目录名不会出现在 URL 中。
如果要使用多个静态资源目录,请多次调用 express.static 中间件函数:

app.use(express.static('public'))
app.use(express.static('files'))

访问静态资源文件时,express.static 中间件函数会根据目录的添加顺序查找所需的文件。

9、核心概念:中间件

一般学习面向对象编程的时候,我们都会听到一句话:一切皆对象。而在学习express的过程中,很深的一个感受就是:一切皆中间件。比如常见的请求参数解析、cookie解析、gzip等,都可以通过中间件来完成。

1.常用中间件

包括但不限于如下。body-parser
 compression
 serve-static
 session
 cookie-parser
 morgan
更多常用中间件,可以点击 这里 http://expressjs.com/en/resources/middleware.html
在这里插入图片描述

10、ejs模块

1、什么是EJS

EJS是一个JavaScript模板库,用来从JSON数据中生成HTML字符串。

2、为什么要使用EJS

与最初的JavaScript相比较,一些不太了解你的代码的人可以更容易地通过EJS模板代码看得懂你的代码。
示例:
最终要实现的效果如下:

用户列表
.张三
.李四
.王二

不使用模块情况
这是用javascript实现的代码

var express = require("express");
var app = express();
/**
 用户列表
 .张三
 .李四
 .王二
 *
 */
app.get("/list",function (request,response) {
    var userJson = '{"title":"用户列表一","list":[{"name":"张三"},{"name":"李四"},{"name":"王二"}]}';
    var userObj = JSON.parse(userJson); //json字符串=》json对象

    //var jsonStr = JSON.stringify(json对象) //json对角 =>json字符串
    userObj.list
    var html = '<h1>'+userObj.title+'</h1>' +
        '<ul>' +
        '<li>张三</li>' +
        '<li>李四</li>' +
        '<li>王二</li>' +
        '</ul>';
    response.send(html);
});

app.listen(8080,function () {
    console.log("启动服务成功,监听8080端口");
});


下面学习EJS同样实现上面的功效,它的工作原理如下:
在这里插入图片描述

使用EJS来找回你的明确、维护性良好的HTML代码结构。
注:data是json对象,不能使json字符串。
创建一个EJS模板,命名为userlist.ejs文件,内容如下:

<!---
  %=变量 %
  % js代码 %
-->

<html>
<head>
    <title>ejs模块</title>
    <meta charset="utf-8">
</head>
<body>
<h1><%= title %></h1>
<ul>
    <% for(var i = 0; i<list.length; i++){ %>
    <li><%= list[i].name %></li>
    <%}%>
</ul>
</body>
</html>

组装ejs模板和json数据响应给客户端

var express = require("express");
var ejs = require("ejs");
var app = express();
app.get("/list",function (request,response) {
    var userJson = '{"title":"学生列表","list":[{"name":"张小三"},{"name":"李四"},{"name":"王二"}]}'; //json字符串数据
    var userObj = JSON.parse(userJson);  //json字符串=>json对象

    ejs.renderFile("./userlist.ejs",userObj, function (err,data) {

        if(err){console.log("ejs加载出错"+err);return;}
        console.log(data); //控制台打印ejs模板文件和json对象数据 组装好html代码
        response.send(data); //响应将ejs模板文件和json对象数据 组装好html代码给客户端;
    });
});
app.listen(8080,function () {
    console.log("启动服务成功,监听8080端口");
});


在这里插入图片描述
http://192.168.40.114:8080/list
在这里插入图片描述

3、ejs模板语法

EJS是一个javascript模板库,用来从json数据中生成HTML字符串
• 功能:缓存功能,能够缓存HTML模板;
• <% code %>用来执行javascript代码
模板中输出变量
• 声明变量<% title=“EJS Template engine” %>
• 输出变量<%= username %> 特殊字符将进行转义

<!-- 定义一个数组,遍历输出 --> 
<% users=["Jack","Rose","Alice","Ave"] %> 
<ul>
 <% for(var item in users)
{ %> 
<li> <%= users[item] %> </li> 
<% }
 %> 
</ul>

4、标签含义

• <% ‘脚本’ 标签,用于流程控制,无输出。
• <%_ 删除其前面的空格符
• <%= 输出数据到模板(输出是转义 HTML 标签)
• <%- 输出非转义的数据到模板
• <%# 注释标签,不执行、不输出内容
• <%% 输出字符串 ‘<%’
• %> 一般结束标签
• -%> 删除紧随其后的换行符
• _%> 将结束标签后面的空格符删除

5、包含(include)

通过 include 指令将相对于模板路径中的模板片段包含进来。(需要提供 ‘filename’ 参数。) 例如,如果存在 “./views/users.ejs” 和 “./views/user/show.ejs” 两个模板文件,你可以通过 <%- include(‘user/show’); %> 代码包含后者。
你可能需要能够输出原始内容的标签 (<%-) 用于 include 指令,避免对输出的 HTML 代码做转义处理。

<ul>
    <% users.forEach(function(user){ %>
    <%- include('user/show', {user: user}); %>
    <% }); %>
</ul>

6、学习网站
  1. https://ejs.bootcss.com/
    在这里插入图片描述

11. Express框架开发web应用程序示例

1. 项目目录结构

在这里插入图片描述

2. 默认模板与路径更改
/设置默认模板引擎是html
app.engine('.html', ejs.__express);
app.set('view engine', 'html');
app.set("views","view");  //模板所在的目录为view
3. 静态资源所有目录
app.use(express.static('public')); //静态资源所有目录
4. Response对象方法

(1)response.render方法用于渲染网页模板。

app.get("/", function(request, response) {
  response.render("index", { message: "Hello World" });});

上面代码使用render方法,将message变量传入index模板,渲染成HTML网页。

response.render('user/user',{"title":"学生列表","list": [ { "name":"张三"},{"name":"李四"}]});

上述代码等价于下面代码ejs.renderFile, 将指定模板文件与json数据组装成html代码,发送给客户端

ejs.renderFile("./view/user/user.html", {"title":"学生列表","list": [ { "name":"张三"},{"name":"李四"}]} , function (err,data) {
    if(err){
        console.log("ejs模板加载出错"+err);
        return;
    }
    response.send(data);
});

(2)response.redirect方法
response.redirect方法允许网址的重定向。可以重定向到静态文件

response.redirect("/hello/anime");
response.redirect("http://www.example.com");
response.redirect(301, "http://www.example.com");

(3)response.sendFile方法
response.sendFile方法用于发送文件。

response.sendFile("/path/to/anime.mp4");
5. 参数解析-body-parser模块使用
app.use(bodyParaser.json()); //解析json类型数据
app.use(bodyParaser.urlencoded({extended:false})); //expanded:false表示解析值类型是string|Array, true表示解析值是任意类型

接收Post请求参数

var userName = req.body.name;
var passWord = req.body.password;

接收Get请求参数

var userName = req.query.name;
var passWord = req.query.password;
6. 重定向与页面渲染

在这里插入图片描述

7. 错误

问题1
下述代码会报错

app.use(indexRouter);
app.use(bodyParser.urlencoded({extended:false})); //expanded:false表示解析值类型是string|Array, true表示解析值是任意类型

改为交换两行代码位置后正常

//必须放到路由前面
app.use(bodyParser.urlencoded({extended:false})); //expanded:false表示解析值类型是string|Array, true表示解析值是任意类型
app.use(indexRouter);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值