Express框架入门:初级篇

QZJLeslie 5年前
   <p><a href="/misc/goto?guid=4958522262563415188" rel="nofollow,noindex">express</a> 是nodejs的一个流行的web框架。本文主要介绍将express作为服务端对外提供API接口时,需要了解的入门知识。</p>    <h2>1. Hello World</h2>    <p>首先安装node(如果已安装,则略过):</p>    <pre>  <code class="language-javascript">$ brew install node</code></pre>    <p>创建一个项目,然后安装express:</p>    <pre>  <code class="language-javascript">$ mkdir express-hello-world && cd express-hello-world  $ npm init  $ npm install express --save</code></pre>    <p>npm init 会提示输入一些配置信息,回车使用默认值即可,执行完后,当前目录下会自动创建 package.json 文件。</p>    <p>npm install express --save 表示为当前项目安装express依赖,该依赖信息会保存在 package.json 文件中。</p>    <p>新建文件 index.js 文件, 输入以下内容:</p>    <pre>  <code class="language-javascript">var express =  require('express');  var app = express();    app.get('/', function(req, res) {    res.send('hello, world!');  });    app.listen(3000);</code></pre>    <p>运行:</p>    <pre>  <code class="language-javascript">$ node index.js</code></pre>    <p>浏览器访问: http://localhost:3000/ ,会输出”hello, world!”。</p>    <h2>2. 中间件middleware</h2>    <p>在express中,中间件(middleware)函数是一种特殊的函数,它可以访问一个http请求周期中的request对象、response对象,以及表示调用栈中的下一个中间件函数的引用,如:</p>    <pre>  <code class="language-javascript">function (req, res, next) {      next();  }</code></pre>    <p>其中, req , res 和 next 三个参数名是约定的,不要使用其它的变量名。中间件函数可以修改request和response,或者提前结束response,也可以调用 next() 表示将执行传递给调用栈中的下一个中间件函数。</p>    <p>如果当前中间件函数没有结束HTTP请求,则必须调用 next() 将执行传递给下一个中间件函数,否则请求会挂起。</p>    <p>使用 app.use() 加载中间件函数,中间件函数加载的顺序决定了它的执行顺序,即先加载,先执行。</p>    <p>在上面hello-world的例子中,我们增加两个简单的中间件函数,分别打印两条日志信息。在 var app = express(); 的后面增加以下代码:</p>    <pre>  <code class="language-javascript">app.use(function (req, res, next) {    console.log('in middleware one...');    next();  });    app.use(function (req, res, next) {    console.log('in middleware two...');    next();  });</code></pre>    <p>执行后,终端会依次输出两个中间件函数中的日志信息。</p>    <p>express中的中间件可以分为以下几类:</p>    <ul>     <li>app级中间件</li>     <li>router级中间件</li>     <li>错误处理中间件</li>     <li>内置中间件</li>     <li>第三方中间件</li>    </ul>    <p>这里仅简要介绍一下主要的app级中间件和router级中间件。</p>    <p>app级中间件,即将中间件函数绑定到 app 对象(即使用 express() 得到的对象),通过 app.use() 或者 app.METHOD() 方法来加载中间件函数,其中 METHOD() 表示HTTP请求中的 GET/POST/PUT 等方法。上面的hello-world示例中就是app级中间件:</p>    <pre>  <code class="language-javascript">app.get('/', function(req, res) {    res.send('hello, world!');  });</code></pre>    <p>router级中间件与app级中间件的用法基本一致,不同的是,它将中间件函数绑定到 express.Router() 对象,通过 router.use() 或者 router.METHOD() 方法来加载。比如上面的app级中间件,用router级中间件的方法改写如下:</p>    <pre>  <code class="language-javascript">var router = express.Router();  router.get('/', function(req, res) {    res.send('hello, world!');  });    app.use('/', router);</code></pre>    <p>引入router级中间件的好处之一是解耦,通过router去分层,然后app加载router。</p>    <h2>3. HTTP的req对象</h2>    <h2>3.1 req.params取路径参数</h2>    <p>express中,路径参数使用命名参数的方式,比如路径是 /user/:id ,则使用 req.params.id 取参数 :id 的值,如:</p>    <pre>  <code class="language-javascript">/user/:id  GET /user/15  req.params.id  => 15</code></pre>    <h2>3.2 req.query取查询参数</h2>    <p>取查询参数,只需要通过 req.query 根据key取值即可,如:</p>    <pre>  <code class="language-javascript">GET /search?name=Ketty&gender=male  req.query.name => Ketty  req.query.gender => male    GET /search?user[name]=Ketty&user[age]=30  req.query.user.name => Ketty  req.query.user.age  => 30</code></pre>    <h2>3.3 req.body</h2>    <p>要取HTTP请求中的body内容,使用 req.body ,但是需要借助第三方module,如 body-parser 和 multer ,以下示例来自 <a href="/misc/goto?guid=4959677001305245382" rel="nofollow,noindex">express文档</a> :</p>    <pre>  <code class="language-javascript">var app = require('express')();  var bodyParser = require('body-parser');  var multer = require('multer'); // v1.0.5  var upload = multer(); // for parsing multipart/form-data    app.use(bodyParser.json()); // for parsing application/json  app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded    app.post('/profile', upload.array(), function (req, res, next) {    console.log(req.body);    res.json(req.body);  });</code></pre>    <h2>3.4 req.get()</h2>    <p>提取HTTP header中的信息,其中,key是不区分大小写的,如:</p>    <pre>  <code class="language-javascript">req.get('Content-Type');    // text/html  req.get('content-type');    // text/html</code></pre>    <h2>4. HTTP的res对象</h2>    <h2>4.1 res.status()</h2>    <p>该方法仅仅是设置状态码,返回response还需调用 send()/end() 等方法,如:</p>    <pre>  <code class="language-javascript">res.status(200).end();  res.status(401).send("error: unauthorized!");</code></pre>    <h2>4.2 res.json()</h2>    <p>返回json格式的信息,res会自动设置response的 Content-Type 为 application/json ,如:</p>    <pre>  <code class="language-javascript">res.status(401).json({"error": "unauthorized"});</code></pre>    <h2>4.3 res.send()</h2>    <p>发送HTTP响应信息,参数可以是字符串、数组、Buffer对象等,会根据参数的类型自动设置header的 Content-Type ,如:</p>    <pre>  <code class="language-javascript">res.send(new Buffer("buffer info"));        // Content-Type: application/octet-stream  res.send("<small>small text</small>");      // Content-Type: text/html  res.send({message: "Welcome"});             // Content-Type: application/json</code></pre>    <h2>4.4. res.set()</h2>    <p>设置HTTP的header信息,如:</p>    <pre>  <code class="language-javascript">res.set('Content-Type','application/pdf');  res.setHeader('Content-Disposition','attachment; filename=cnb.pdf');</code></pre>    <h2>4.5 res.render()</h2>    <p>使用模板引擎渲染页面,然后作为response返回。如果参数表示的文件名不带后缀,则会根据模板引擎的设置,自动推断后缀;如果文件名带后缀,则会加载该后缀对应的模板引擎模块。如</p>    <pre>  <code class="language-javascript">res.render('index');</code></pre>    <p>如果默认的模板引擎是jade,则express会从对应的路径下查找index.jade文件并渲染。</p>    <p> </p>    <p>来自:http://nkcoder.github.io/2016/08/20/express-tutorial-basic/</p>    <p> </p>