Node.js历险记之express框架入门篇

转载请注明出处:http://blog.csdn.net/gamer_gyt
博主微博:http://weibo.com/234654758
Github:https://github.com/thinkgamer


写在前面的话

Express 是一种保持最低程度规模的灵活 Node.js Web 应用程序框架,为 Web 和移动应用程序提供一组强大的功能。

环境说明

Ubuntu 16.04


安装express

假设已经安装了nodejs

mkdir myapp
cd myapp

实用npm init 命令为应用程序创建package.json文件 关于package.json的更多信息参考:https://docs.npmjs.com/files/package.json
npm init 输入相应的信息

安装express框架,如果要将express保存到依赖库中后面跟–save,否则不跟

npm install express --save

这里解释下这个 --save,就是把安装的express 和对应的版本号写进packages.json文件中,如果事先在package.json中写入了依赖,那么直接执行npm install即可
在此基础上我们来创建我们的HelloWorld
创建app.js,添加以下内容

var express = require('express');
var app = express();
app.get('/', function (req, res) {
  res.send('Hello World!');
});
app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});

执行node app.js 报错

Cannot find module ‘express’

分析:在安装express时已经指定了 --save,我也尝试了 -g ,但是依旧还是这个问题,后来查资料发现说是 -g安装的位置(用户目录)与node安装路径的位置不在同一个目录导致的,需要配置以下NODE_PATH,ok,我们来配置下环境变量

vim ~/.bashrc

加入(/home/master/.nvm/versions/node/v6.9.5/bin 是我node的位置)

#nodejs
export NODE_PATH=/home/master/.nvm/versions/node/v6.9.5/bin
export PATH=$PATH:$NODE_PATH

此时再执行node app.js ,浏览器访问 localhost:3000
express


express应用程序生成器

除了手动创建程序的各个文件,我们也可以使用express应用程序生成器生成整个框架

1 . 安装

npm install express-generator -g
可以使用-h来查看帮助

master@ubuntu:~/Desktop$ express -h
  Usage: express [options] [dir]
  Options:
    -h, --help           output usage information
        --version        output the version number
    -e, --ejs            add ejs engine support
        --pug            add pug engine support
        --hbs            add handlebars engine support
    -H, --hogan          add hogan.js engine support
    -v, --view <engine>  add view <engine> support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
    -c, --css <engine>   add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css)
        --git            add .gitignore
    -f, --force          force on non-empty directory

2 . 创建myapp的应用程序

express --view=pug myapp

master@ubuntu:~/Desktop$ express --view=pug myapp
   create : myapp
   create : myapp/package.json
   create : myapp/app.js
   create : myapp/public
   create : myapp/public/javascripts
   create : myapp/public/images
   create : myapp/public/stylesheets
   create : myapp/public/stylesheets/style.css
   create : myapp/routes
   create : myapp/routes/index.js
   create : myapp/routes/users.js
   create : myapp/views
   create : myapp/views/index.pug
   create : myapp/views/layout.pug
   create : myapp/views/error.pug
   create : myapp/bin
   create : myapp/bin/www
   install dependencies:
     $ cd myapp && npm install
   run the app:
     $ DEBUG=myapp:* npm start

3 . 安装依赖

cd myapp
npm install

4 . 启动服务

npm start

浏览器访问
http://localhost:3000/
express


Express 的基本路由

路由由于确定应用程序如何响应对特定端点的请求机会,包含一个URL(或路径)和一个特定的请求方法(GET,POST等)。每个路由都有一个或多个处理程序函数,这些函数在路由匹配时执行。
路由定义采用以下结构:

app.METHOD(PATH, HANDLER)

其中:

  • app 是espress的实例
  • METHOD是HTTP请求方法
  • PATH是服务器上的路径
  • HANDLER是在路由匹配时执行的函数

路由方法派生自HTTP方法之一,以下代码是为访问应用程序根目录的GET和POST方法定义的路由示例

// GET method route
app.get('/', function (req, res) {
  res.send('GET request to the homepage');
});
// POST method route
app.post('/', function (req, res) {
  res.send('POST request to the homepage');
});

Express 支持对英语HTTP方法的以下路由方法:get,post,put,head,delete,options,trace,copy,lock,mkcol,move,purge,propfind,proppatch,unlock,report,mkactivity,ceckout,merge,msearch,notify,subscribe,unsubscribe,patch,connect。

有一种特殊的路由方法:app.all() ,他并非派生自HTTP方法,该方法用于在所有请求方法的路径中装入中间件函数。在以下示例中,无论使用GET。POST,PUT,DELETE还是http模块中支持的其他任何HTTP请求方法,都将为针对 “/secret” 的请求执行处理程序。

app.all('/',function(req,res,next){
  console.log('Accessing the secret section...');
  next();  //pass control to the next handle
});

路由路径
路由路径与请求方法相结合,用于定义可以在其中提出请求的端点。路由路径可以是字符串,字符串模式或正则表达式。以下是基于字符串路由的一些示例:

// 此路由路径将请求与根路由 / 匹配。
app.get('/',function(req,res){
  res.send('root');
});
//此路由路径将请求与 /about 匹配。
app.get('about',function(req,res){
  res.send('about');
});
//此路由路径将请求与 /random.text 匹配。
app.get('/random.text',function(req,res){
  res.send('random.text');
});
//以下是基于字符串模式的路由路径的一些示例。
//此路由路径将匹配 acd 和 abcd。
app.get('/ab?cd',function(req,res){
  res.send('ab?cd')
});
//此路由路径将匹配 abcd、abbcd、abbbcd 等。
app.get('/ab+cd',function(req,res){
  res.send('ab+cd');
});
//此路由路径将匹配 abcd、abxcd、abRABDOMcd、ab123cd 等。
app.get('ab*cd',function(req,res){
  res.send('ab*cd');
});
//此路由路径将匹配 /abe 和 /abcde。
app.get('/ab(cd)?e',function(req,res){
  res.send('/a/');
});
//基于正则表达式的路由路径的示例:
//此路由路径将匹配名称中具有“a”的所有路由。
app.get(/a/,function(req,res){
  res.send('/a/');
});
// 此路由路径将匹配 butterfly 和 dragonfly,但是不匹配 butterflyman、dragonfly man 等。
app.get(/.*fly$/,function(req,res){
  res.send('/.*fly$/');
});

路由处理程序

你可以提供多个回调函数,以类似与中间件的行为方式来处理请求,唯一例外是这些回调函数可能调用 next(‘route’) 来绕过省区的路由回调,你可以使用此机制对路由施加先决条件,在灭有路由继续执行当前路由的情况下,可将控制权传递给后续路由。路由处理程序的形式可以是一个函数,一组函数,或者两者的结合,如下示例所示:

//单个回调函数可以处理一个路由。例如:
app.get('/example/a',function(req,res){
  res.send('Hello from A');
});
//多个回调函数可以处理一个路由(确保您指定 next 对象)。例如:
app.get('/example/b', function(req,res,next){
  console.log('the respnse will be sent by the next function');
  next();
},function(req,res){
  res.send('Hello from B');
});
//一组回调函数可以处理一个路由。例如:
var cb0 = function(req,res,next){
  console.log('CB0');
  next();
};
var cb1 = function(req,res,next){
  console.log('CB1');
  next();
};
var cb2 = function(res,res){
  res.send('Hello from C');
};
app.get('/example/c',[cb0,cb1,cb2]);
//独立函数与一组函数的组合可以处理一个路由。例如:
var ab1 = function(req,res,next){
  console.log('AB1');
  next();
};
var ab2 = function(req,res,next){
  console.log('AB2');
  next();
}
app.get('/example/d',[ab1,ab2],function(req,res,next){
  console.log('the response will be sent by the next function ...');
  next();
},function(req,res){
  res.send('Hello from D');
});

响应方法

下表中响应独享(res)的方法可以向客户机发送响应,并终止请求/响应循环。如果没有从路由处理程序调用其中任何方法,客户机请求将保持挂起状态。

方法描述
res.download()提示将要下载文件。
res.end()结束响应进程。
res.json()发送 JSON 响应。
res.jsonp()在 JSONP 的支持下发送 JSON 响应。
res.redirect()重定向请求。
res.render()呈现视图模板。
res.send()发送各种类型的响应。
res.sendFile以八位元流形式发送文件。
res.sendStatus()设置响应状态码并以响应主体形式发送其字符串表示

app.route()

你可以使用app.route() 为路由路径创建可链接的路由处理程序,因为在单一位置指定路径,所以可以减少冗余和输入错误,有关路由的更多信息,请参阅:http://expressjs.com/zh-cn/4x/api.html#router

//以下是使用 app.route() 定义的链式路由处理程序的示例。
app.route('/book')
  .get(function(req,res){
    res.send('Get a random book');
  })
  .post(function(req,res){
    res.send('add a book');
  })
  .put(function(req,res){
    res.send('update the book');
  });

express.Router

使用express.Router类来创建可安装的模块化路由处理程序,Router实例是完整的中间件和路由系统,因此,常常将其称为" 微型应用程序"。以下示例将路由器创建为模块,在其中装入中间件,定义一些路由,然后安装在主应用程序的路径中。
在应用程序中创建birds.js文件,写入以下内容:

var express = require('express')
var router = express.Router();
// middleware that is specific to this router
router.use(function(req,res,next){
  console.log('Time:' ,Date.now());
  next();
});
// define the home page route
router.get('/',function(req,res){
  res.send('Birds home page');
});
// define the about route
router.get('/about',function(req,res){
  res.send('About birds');
})
module.exports = router

在app.js中引用

var birds = require('./birds');
var express = require('express');
var app = express();
app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});
app.use('/birds',birds);

此应用程序现在可针对 /birds 和 /birds/about 的请求,调用特定于此路由的 timeLog 中间价函数。


在Express中提供静态文件

为了提供诸如图像、CSS 文件和 JavaScript 文件之类的静态文件,请使用 Express 中的 express.static 内置中间件函数。

将包含静态资源的目录的名称传递给 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 以您使用 express.static 中间件函数设置静态目录的顺序来查找文件。

要为 express.static 函数提供的文件创建虚拟路径前缀(路径并不实际存在于文件系统中),请为静态目录指定安装路径,如下所示:

app.use(’/static’, express.static(‘public’));

现在,可以装入具有 /static 路径前缀的 public 目录中的文件。

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

然而,向 express.static 函数提供的路径相对于您在其中启动 node 进程的目录。如果从另一个目录运行 Express 应用程序,那么对于提供资源的目录使用绝对路径会更安全:

app.use(’/static’, express.static(__dirname + ‘/public’));

Express框架的入门篇基本就是上边这些内容了,截止到这里我们并没有演示一个完整的例子,那么下面我们来看一个表单提交的例子,在以上代码的基础上。


使用GET方式提交表单

1:创建静态文件夹

在项目myapp 目录下创建public (存放img,js,css文件)和templates(存放html文件)

2:app.js 如下

var express = require('express');
// var birds = require('./birds');
var app = express();
app.use(express.static('public'));  //static file
app.use(express.static('templates'));  //static file
//
// app.listen(3000, function () {
//   console.log('Example app listening on port 3000!');
// });
app.get('/index.html', function (req, res) {
   res.sendFile( __dirname + "/" + "index.html" );
})
app.get('/form_get', function (req, res) {
   // 输出 JSON 格式
   response = {
       username:req.query.username,
       email:req.query.email,
   };
   console.log(response);
   res.end(JSON.stringify(response));
})
var server = app.listen(3000, function () {
  var host = server.address().address
  var port = server.address().port
  console.log("应用实例,访问地址为 http://%s:%s", host, port)
})

3:index.html 如下(位于 根目录的templates文件夹下)

<html>
<head>
    <meta charset="UTF-8">
    <title>test</title>
    <link rel="stylesheet" href="http://127.0.0.1:3000/css/index.css">
</head>
<div class="login-main">
<h3 align="center">------------Login-------------</h3>
    <form role="form" method="get" action="http://127.0.0.1:3000/form_get">
            <input class="incon" name="username" type="text" placeholder="username">
            <input class="incon" name="email" type="text" placeholder="email">
            <input class="btnincon"  type="submit" value="登录">
            <hr style="height:1px;border:none;border-top:1px solid darkgray;" />
    </form>
</table>
</div>
</body>
</html>

4:index.css

/*登录注册样式 */
hr{margin-bottom: 5px;}
.loginbody{ background-repeat: no-repeat; background-size:cover;}
.login-main{width:400px; height: 300px;margin: auto; overflow: hidden; margin-top:8%; border-radius: 4px; border: 1px solid darkgray;
    box-shadow: -10px 10px 20px gray;}
.login-main h3{ text-indent: 0.5em;}
.incon{ width: 360px; font-size: 16px; margin-left:20px; margin-top:20px; height: 38px; border-radius: 2px; text-indent: 1em;}
.btnincon{ width: 200px; font-size: 16px; margin-left:100px; margin-top:20px; height: 38px; border-radius: 2px; text-indent: 1em;}

5:查看效果

express

输入相应内容
express


使用POST方式提交表单

1:修改html文件

把html文件中的method改为 post,action中的form_get 改成form_post

2:在app.js中添加

var bodyParser = require('body-parser');
// 创建 application/x-www-form-urlencoded 编码解析
var urlencodedParser = bodyParser.urlencoded({ extended: false })
app.post('/form_post', urlencodedParser, function (req, res) {
   // 输出 JSON 格式
   response = {
       username:req.bod.username,
       email:req.body.email,
   };
   console.log(response);
   res.end(JSON.stringify(response));
})

3:执行

npm install body-parser --save

重新测试会看到同样的效果


文件上传功能

1:index.html

<html>
<head>
<title>文件上传表单</title>
</head>
<body>
<h3>文件上传:</h3>
选择一个文件上传: <br />
<form action="/file_upload" method="post" enctype="multipart/form-data">
<input type="file" name="image" size="50" />
<br />
<input type="submit" value="上传文件" />
</form>
</body>
</html>

2:app.js

var express = require('express');
var app = express();
var fs = require("fs");
var bodyParser = require('body-parser');
var multer  = require('multer');
app.use(express.static('public'));
app.use(express.static('templates'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(multer({ dest: '/tmp/'}).array('image'));
app.get('/index.html', function (req, res) {
   res.sendFile( __dirname + "/" + "index.html" );
})
app.post('/file_upload', function (req, res) {
   console.log(req.files[0]);  // 上传的文件信息
   var des_file = __dirname + "/" + req.files[0].originalname;
   fs.readFile( req.files[0].path, function (err, data) {
        fs.writeFile(des_file, data, function (err) {
         if( err ){
              console.log( err );
         }else{
               response = {
                   message:'File uploaded successfully',
                   filename:req.files[0].originalname
              };
          }
          console.log( response );
          res.end( JSON.stringify( response ) );
       });
   });
})
var server = app.listen(3000, function () {
  var host = server.address().address
  var port = server.address().port
  console.log("应用实例,访问地址为 http://%s:%s", host, port)
})

执行

npm install fs --save
npm install multer --save

效果图

express

express


上一篇: Node.js历险记之剑未配好,已出江湖
【技术服务】,详情点击查看: https://mp.weixin.qq.com/s/PtX9ukKRBmazAWARprGIAg

扫一扫 关注微信公众号!号主 专注于搜索和推荐系统,尝试使用算法去更好的服务于用户,包括但不局限于机器学习,深度学习,强化学习,自然语言理解,知识图谱,还不定时分享技术,资料,思考等文章!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值