• Express4.x API (一):application (译) -- 完成
  • Express4.x API (二):request (译) -- 完成
  • Express4.x API (三):Response (译) -- 完成
  • Express4.x API (四):router (译) -- 完成

写在前面

Express文档核心的四大部分app,request,response,router,基本上已经完成。简单的总结

  1. 通过调用express()返回得到的app实际上是一个JavaScript的Function,它是一个Express的应用实例;app对象具有HTTP请求,配置中间件,渲染HTML视图,注册模板引擎这四大功能。它还有一些属性设置,这些属性可以改变程序的行为

  2. request对象即表示HTTP请求,包含了请求查询字符串,参数,内容,HTTP头等属性

  3. response对象则表示HTTP响应,即在受到请求时向客户端发送的HTTP响应数据

  4. 每个Express程序有一个内建的app路由,顶层的express对象有一个Router()方法,你可以使用Router()来创建一个新的router对象,你可以把它当做一个mini-application,它具有操作路由和中间件的能力,有些方法和app类同

技术库更迭较快,很难使译文和官方的API保持同步,我们只有提升自己的英语能力才能更快的适应库的更新迭代,阅读到最新资料。
所以我此次翻译的目的,一是熟悉express文档,二是锻炼自己英语阅读能力;

原文地址:express.com

Application

app对象是指一个Express应用程序,通过调用的顶层的express()函数创造它

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

app对象有以下这些方法

  • 路由HTTP请求;例如:app.METHOD和app.param
  • 配置中间件;例如:app.router
  • 渲染HTML视图;例如:app.render
  • 注册模板引擎;例如:app.engine

他还具有影响应用程序行为的设置(属性);获得更多的信息,见Application settings

Properties

app.locals

app.locals是一个JavaScript对象,它的属性是应用程序中的局部变量

app.locals.title  // "My App"app.locals.email  // "me@myapp.com"

一旦设置,app.locals属性的值将会贯穿整个生命周期。对比res.locals属性的特性,res.locals仅适用于请求的生命周期

你可以访问应用程序中呈现的模板中的本地变量,这对于想模板提供协助函数以及app-level非常有用。但是请注意,您不能访问中间件的局部变量

app.locals.title = "My App";
app.locals.strftime = require('strftime');
app.locals.email = 'me@myapp.com';

app.mountpath

app.mountpath属性是路径模式的子应用程序安装

子应用程序是一个Express实例,可以用于处理对路由的请求

var express = require('express');var app = express();  // 主要的应用程序
var admin = express();  // 子应用程序admin.get('/',function(req,res){console.log(admin.mountpath)  // adminres.send('Admin Homepage');
})app.use('/admin',admin) // 挂载子应用程序

这类似于req对象中的baseUrl属性,除了baseUrl返回匹配的URL路径,而不是匹配的模式(s).

如果子应用程序挂载在多个路径模式上,app.mountpath返回它挂载的模式列表,像下面所展示的例子这样:

var admin = express();admin.get('/',function(req,res){console.log(admin.mountpath)   // [ '/adm*n','/manager' ]res.send('Admin Homepage');
});var secret = express();
secret.get('/',function(req,res){console.log(secret.mountpath); //secr*tres.send('Admin Secret');
});admin.use('/secr*t', secret);
app.use(['/adm*n', '/manager'], admin);

Events

app.on('mount',callback(parent))

当子程序被挂载到父程序时,mount事件被发射。父程序对象作为参数,传递给回调方法。

var admin = express();admin.on('mount',function(parent){console.log('Admin Mount');console.log(parent);   // 指父应用程序
})admin.get('/',function(req,res){res.send('Admin homePage');
});app.use('/admin',admin);

Methods

app.all(path,callback[,callback ...])

app.all方法和标准的app.METHOD()方法类似,除了它匹配所有的HTTP动词。对于给一个特殊前缀映射一个全局的逻辑处理,或者无条件匹配,它是很有效的。例如,如果你把下面内容放在所有其他的路由定义的前面,它要求所有从这个点开始的路由需要认证和自动加载一个用户。这些回调并不一定是终点:loadUser可以在完成了上一个任务后,调用next()来继续匹配随后的路由。

app.all('*',requireAuthentication,loadUser)

或者这种相等的形式:

app.all('*',requireAuthentication);
app.all('*',loadUser)

另一个例子是全局白名单的方法(white-listed “global” functionality)。这个例子和前面很像,然而它只是限制以/api开头的路径。

app.all('/api/*',requireAuthentication);

app.delete(path, callback [, callback ...])

路由HTTP DELETE请求到有特殊回调方法的特殊的路径。获取更多的信息,可以查阅routing guide

你可以提供多个回调函数,他们的作用和中间件一样,除了这些回调可以通过调用next('router')来绕过剩余的路由回调。你可以使用这个机制来为一个路由设置一些前提条件,如果不能满足当前路由的处理条件,那么你可以传递控制到随后的路由。

app.delete('/',function(req,res){res.send('DELETE request to homepage');
})

app.disable(name)

将设置名为name的值为false,此处的name是app settings table中各属性的一个。调用app.set('foo',false)和app.disable('foo')是等价的

app.disable('trust proxy');
app.get('trust proxy');   // false

app.disabled(name)

如果name被禁用则返回true,此处的name是app settings table中各属性的一个

app.disabled('trust proxy');  // true
app.enable('trust proxy');
app.disabled('trust proxy');  // false

app.enable(name)

设置布尔类型的设置值name为true,此处的name是app settings table中各属性的一个。调用app.set('foo', true)和调用app.enable('foo')是等价的。

app.enable('trust proxy');
app.get('trust proxy')  // true

app.enabled(name)

如果name可用则返回true,此处的name是app settings table中各属性的一个。

app.enabled('trust proxy')   // false
app.enable('trust proxy')
app.enabled('trust proxy')   // true

app.engine(ext,callback)

注册给定引擎的回调,用来渲染ext文件。默认情况下,Express需要使用require()来加载基于文件扩展的引擎。例如,如果你尝试渲染一个foo.jade文件,Express在内部调用下面内容,同时缓存require()结果供随后来调用去提高性能

app.engine('jade',require('jade').__express);

使用下面这种方法,来处理没有办法开箱即用的.express方法的模板,或者你希望使用不同的扩展名。

举个栗子,使用ejs模板引擎来渲染.html文件:

app.engine('html',require('ejs').renderFile);

在这个例子中,ejs提供了一个.renderFile方法,这个方法满足了Express规定的签名规则:(path, options, callback),然而记住在内部它只是ejs.__express的一个别名,所以你可以在不做任何事的情况下直接使用.ejs扩展。一些模板引擎没有遵循这种规范,consolidate.js库映射模板引擎以下面的使用方式,所以他们可以无缝的和Express工作。

var engines = require('consolidate');
app.engine('haml',engines.haml);
app.engine('html',engines.hogan);

app.get(name)

获得设置名为name的app设置的值,此处的name是app settings table中各属性的一个。 如下:

app.get('title');  // => undefined
app.set('title','My site');
app.get('title')  // 'My site'

app.get(path, callback [, callback ...])

使用指定的回调函数将HTTP请求路由到指定的路径。获取跟多的信息,可以查阅routing guide。你可以提供多个回调函数,他们的内容和中间件一样,除了这些回调可以通过调用next('router')来绕过剩余的路由回调。你可以使用这个机制来为一个路由设置一些前提条件,如果请求没能满足当前路由的处理条件,那么传递控制到随后的路由。

app.get('/',function(req,res){res.send('GET request to homepage')
})

app.listen(port, [hostname], [backlog], [callback])

绑定程序监听端口到指定的主机端口号。这个方法和Node中的http.Server.listen()是一样的

var express = require('express')
var app = express();
app.listen(3000);

通过调用express()返回得到的app实际上是一个JavaScript的Function,被设计用来作为一个回调传递给NODE HTTP servers来处理请求。这样,其就可以很简单的基于同一份代码提供的http和https版本,所以app没有从这些继承(它只是一个简单的回调)。

var express = require('express');
var https = require('https');
var  http = require('http');http.createServer(app).listen(80);
http.createServer(options,app).listen(443)

app.listen()方法是下面所示的一个便捷的方法(只针对HTTP协议):

app.listen = function(){var server = http.createServer(this);return server.listen.apply(server, arguments);
}

app.METHOD(path,callback [,callback ...])

路由HTTP请求,METHOD是这个请求的HTTP方法,比如GET,POST,PUT等等,小写。所以,实际方法是app.get,app.post,app.put等等,下面有关于方法完整的表。

获取更多信息,请看routing guide。 Express支持下面的路由方法,对应与同名的HTTP方法:

具体见app.METHOD

如果使用上述方法时,导致了无效的JavaScript变量名,可以使用中括号,比如:app['m-search']('/', function ....

你可以提供多个回调函数,它们的行为和中间件一样,除了这些回调可以通过调用next('router')来绕过剩余的路由回调。你可以使用这个机制来为一个路由设置一些前提条件,如果请求没有满足当前路由的处理条件,那么传递控制到随后的路由。(我的话:"!这一段看了好几遍啦- -,理解next传递非常重要性")

本API文档把使用比较多的HTTP方法app.get(),app.post,app.put(),app.delete()作为一个个单独的项进行说明。然而,其他上述列出的方法以完全相同的方式工作。

有一种特殊的路由方法,app.all(),这不是来自任何HTTP方法。他在所有请求方法的路径上加载中间件,其对于所有的方法都有效

app.param([name],callback)

给路由参数添加回调触发器,这里的name是参数名或者参数数组,function是回调方法。回调方法的参数按序是请求对象,响应对象,下个中间件,参数值和参数名。 如果name是数组,会按照各个参数在数组中被声明的顺序将回调触发器注册下来。还有,对于除了最后一个参数的其他参数,在他们的回调中调用next()来调用下个声明参数的回调。只有一个参数,那么就是最后一个参数,和数组中最后一个参数是一样的。 例如,当:user出现在路由路径中,你可以映射用户加载的逻辑处理来自动提供req.user给这个路由,或者对输入的参数进行验证。

app.param('user'.function(req,res,next,id){// 尝试从用户模型获取用户详细信息并将其附加到请求对象User.find(id,function(err,user){if(err){next(err);}else if(user){req.user = user;next();}else{next(new Error('fail to load user'))}})
})

对于Param的回调定义的路由来说,他们是局部的。它们不会被挂载的app或者路由继承。所以,定义在app上的Param回调只有是在app上的路由具有这个路由参数时才起作用。

在定义param的路由上,param回调都是第一个被调用的,它们在一个请求-响应循环中都会被调用一次并且只有一次,即使多个路由都匹配,如下面的栗子:

app.param('id',function(req,res,next,id){console.log('CALLED ONLY NOCE');next();
})app.get('/user/:id',function(req,res,next){console.log('although this match');next();
})app.get('/user/:id',function(req,res){console.log('and this matches too');res.end();
})

当GET/user/42,得到下面结果

 CALLED ONLY NOCEalthough this matchesand this matches too
app.param(['id','page'],function(req,res,next,value){console.log('CALLED ONLY ONCE with',value);next();
})app.get('/user/:id/:page',function(){console.log('although this matches');next();
})app.get('/user/:id/:page',function(){console.log('and this matchs too');res.end();
})

当执行GET /user/42/3,结果如下:

CALLED ONLY ONCE with 42
CALLED ONLY ONCE with 3
although this matches
and this mathes too

下面章节描述的app.param(callback)在v4.11.0之后被弃用。

通过只传递一个回调参数给app.param(name, callback)方法,app.param(naem, callback)方法的行为将被完全改变。这个回调参数是关于app.param(name, callback)该具有怎样的行为的一个自定义方法,这个方法必须接受两个参数并且返回一个中间件。 这个回调的第一个参数就是需要捕获的url的参数名,第二个参数可以是任一的JavaScript对象,其可能在实现返回一个中间件时被使用。 这个回调方法返回的中间件决定了当URL中包含这个参数时所采取的行为。

在下面的例子中,app.param(name, callback)参数签名被修改成了app.param(name, accessId)。替换接受一个参数名和回调,app.param()现在接受一个参数名和一个数字。

var express = require('express');
var app = express();// 自定义app.param()的行为
app.param(function(param,option){return function(req,res,next,val){if(val == option){next();}else{res.sendStatus(403);}}
})// 使用定制的app.param()
app.param('id',1337);// 触发捕获的路由
app.get('/user/:id', function (req, res) {res.send('OK');
})app.listen(3000,function(){console.log('Ready');
})
app.param(function(param,validator){return function(req,res,next,val){if(validator(val)){next();}else{res.sendStatus(403);}}
})app.param('id',function(candidate){return !isNaN(parseFloat(candidate)) && isFinite(candidate);
})

在使用正则表达式,不要使用.。例如,你不能使用/user-.+/来捕获user-gami,用使用[\s\S]或者[\w\>W]来代替(正如/user-[\s\S]+/)。

//captures '1-a_6' but not '543-azser-sder'
router.get('/[0-9]+-[[\\w]]*', function);
//captures '1-a_6' and '543-az(ser"-sder' but not '5-a s'
router.get('/[0-9]+-[[\\S]]*', function);
//captures all (equivalent to '.*')
router.get('[[\\s\\S]]*', function); 

app.path()

返回应用程序的规范路径(字符串)

var app = express(), blog = express(), blogAdmin = express();app.use('/blog', blog);
blog.use('/admin', blogAdmin);console.log(app.path()); // ''
console.log(blog.path()); // '/blog'
console.log(blogAdmin.path()); // '/blog/admin'

如果app挂载很复杂下,那么这个方法的行为也会很复杂:一种更好用的方式是使用req.baseUrl来获得这个app的典型路径。

app.post(path, callback, [callback ...])

使用指定的回调函数将HTTP POST请求路由到指定的路径。有关更多信息,请参见routing guide。

你可以提供多个回调函数,它们的行为和中间件一样,除了这些回调可以通过调用next('router')来绕过剩余的路由回调。你可以使用这个机制来为一个路由设置一些前提条件,如果请求没能满足当前路由的处理条件,那么传递控制到随后的路由

app.post('/', function (req, res) {res.send('POST request to homepage');
});

app.put(path, callback [, callback ...])

使用指定的回调函数将HTTP PUT请求路由到指定的路径。有关更多信息,请参见routing guide。

你可以提供多个回调函数,它们的行为和中间件一样,除了这些回调可以通过调用next('router')来绕过剩余的路由回调。你可以使用这个机制来为一个路由设置一些前提条件,如果请求没能满足当前路由的处理条件,那么传递控制到随后的路由

app.put('/', function(req, res) {res.send('PUT request to homepage');
});

app.render(view, [locals], callback)

通过回调函数返回视图的呈现HTML,它可以接受一个可选的参数,可选参数包含了这个view需要用到的本地数据。这个方法类似于res.render(),除了它不能把渲染得到的HTML文本发送给客户端。

将app.render()当作是可以生成渲染视图字符串的工具方法。在res.render()内部,就是使用的app.render()来渲染视图。

如果使能了视图缓存,那么本地变量缓存就会保留。如果你想在开发的过程中缓存视图,设置它为true。在生产环境中,视图缓存默认是打开的。

app.render('email', function(err, html){// ...
});app.render('email', { name: 'Tobi' }, function(err, html){// ...
});

app.route(path)

返回一个单例模式的路由的实例,之后你可以在其上施加各种HTTP动作的中间件。使用app.route()来避免重复路由名字

var app = express();app.route('/events')
.all(function(req, res, next) {// runs for all HTTP verbs first// think of it as route specific middleware!
})
.get(function(req, res, next) {res.json(...);
})
.post(function(req, res, next) {// maybe add a new event...
})

app.set(name, value)

给 name 设置项赋 value 值,name 是 Application settings 中属性的一项。

对于一个类型是布尔型的属性调用app.set('foo', ture)等价于调用app.enable('foo')。同样的,调用app.set('foo', false)等价于调用app.disable('foo')。

可以使用app.get()来取得设置的值:

app.set('title', 'My Site');
app.get('title'); // 'My Site'

Application Settings

如果name是程序设置之一,它将影响到程序的行为。下边列出了程序中的设置。
见 app.set

app.use([path,] function [, function...])

挂载中间件方法到路径上。如果路径未指定,那么默认为"/"。

一个路由将匹配任何路径如果这个路径以这个路由设置路径后紧跟着"/"。比如:app.use('/appale', ...)将匹配"/apple","/apple/images","/apple/images/news"等。

中间件中的req.originalUrl是req.baseUrl和req.path的组合,如下面的例子所示。

app.use('/admin', function(req, res, next) {// GET 'http://www.example.com/admin/new'console.log(req.originalUrl); // '/admin/new'console.log(req.baseUrl); // '/admin'console.log(req.path); // '/new'next();
});

在一个路径上挂载一个中间件之后,每当请求的路径的前缀部分匹配了这个路由路径,那么这个中间件就会被执行。 由于默认的路径为/,中间件挂载没有指定路径,那么对于每个请求,这个中间件都会被执行

 // 此中间件将不允许请求超出它的范围。
app.use(function(req, res, next) {console.log('Time: %d', Date.now());next();
});

路径(path)可以是表示路径的字符串、路径模式、匹配路径的正则表达式或其组合数组

下面是中间件的简单示例:

具体见app.use

下面是一些例子,在Express程序中使用express.static中间件。
为程序托管位于程序目录下的public目录下的静态资源:

// GET /style.css etc
app.use(express.static(__dirname + '/public'));

在/static路径下挂载中间件来提供静态资源托管服务,只当请求是以/static为前缀的时候。

// GET /static/style.css etc.
app.use('/static', express.static(express.__dirname + '/public'));

通过在设置静态资源中间件之后加载日志中间件来关闭静态资源请求的日志。

app.use(express.static(__dirname + '/public'));
app.use(logger());

托管静态资源从不同的路径,但./public路径比其他更容易被匹配:

app.use(express.static(__dirname + '/public'));
app.use(express.static(__dirname + '/files'));
app.use(express.static(__dirname + '/uploads'));

写在后面

到此Express4.x API 译文 系列文章已经完成。

本人学识有限,难免有所纰漏或者理解不当之处,翻译仅仅是方便个人学习交流使用,无其他用意(如果有不妥之处,请联系本人删除),原文地址:expressjs.com

转载于:https://www.cnblogs.com/okaychen/p/8108405.html

Express4.x API (一):application (译)相关推荐

  1. Express4.x API (四):Router (译)

    Express4.x API 译文 系列文章 Express4.x API (一):application (译) -- 完成 Express4.x API (二):request (译) -- 完成 ...

  2. Express4.x api 翻译(draft)

    用了一年多的Express了,其实会用的功能也能基本满足业务的需求,但是总是感觉自己对其的掌握还是缺少一种系统性.故翻译其api,以期自己在翻译过程中对其有更深的认识. API 原文地址 翻译的内容还 ...

  3. SharePoint JavaScript API in application pages

    前言 最近,在SharePoint 应用程序页中写JavaScript API,进行一些数据交互.其实,很简单的事情却遇到了问题,记录一下,希望能对遇到类似问题的人以帮助. 引用JavaScript ...

  4. 架构师之路 — API 经济 — Web、HTTP Server、API Service、Application

    目录 文章目录 目录 Web HTTP Server API Service Application Web Web(World Wide Web,全球广域网),也称:万维网,它是一种基于 HTML( ...

  5. API(Application Programming Interface,应用程序编程接口)

    API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码 ...

  6. [转]SDK与API区别

    转载:https://www.zhihu.com/question/21691705/answer/149935191 SDK(software development kit),中文可译为" ...

  7. python如何调用阿里云接口_python 调用阿里云云解析api添加记录

    首先安装阿里云SDK pip install aliyun-python-sdk-core pip install aliyun-python-sdk-alidns 可以配合jenkins传递参数 # ...

  8. Java 学习API(一)

    文章目录 前言 API 文档注释 String类 创建字符串 拼接字符串 格式化字符串 String方法 substring() indexOf() charAt() trim() startsWit ...

  9. SDK、API、DLL都是什么,了解一下

    网站平台是做能力开放的,有API能力,也有SDK能力.没做过开发的产品汪,刚接触的时候也是傻傻搞不清楚,各种查资料. SDK(software development kit),中文可译为" ...

  10. DLL,SDK,API专业技术术语

    SDK(software development kit),中文可译为"软件开发工具包". 一般都是一些被软件工程师用于为特定的软件包.软件架构.硬件平台.操作系统等建立应用软件的 ...

最新文章

  1. Windows 64位驱动 关闭内存保护
  2. WinForm 实现拖拽功能
  3. linux学习-简单命令介绍及安装VMware Tools
  4. nginx反向代理配置 多个_实例分享:Nginx学习之反向代理WebSocket配置实例
  5. java 不显示imageicon_Java ImageIcon 不能显示问题
  6. ajax js java省市三级联动菜单,AJAX省市区三级联动下拉菜单(java版)
  7. zblog php伪静态,zblogphp如何设置伪静态
  8. Codeforces Round #565 (div. 3)
  9. pythonmkdir语法错误_转--python使用mkdir函数出现错误WindowsError:[Error3]
  10. spark sql 对接 HDFS
  11. 关于培训机构~程序员培训
  12. SourceTree拉取代码出现错误
  13. 如何实现用手机远程控制电脑?
  14. [cv]郑哲东 Deep-ReID——Learn pedestrian representations from
  15. Linux——boot lodaer:grub2核心载入工具
  16. 文件上传、下载、导出(图片上传、下载)
  17. 健美运动员赛前脱水断碳_就金刚狼的问题,谈谈健美比赛前的控水脱水
  18. 论文数据查找和论文参考准确搜索定位
  19. 【Linux】Docker入门
  20. 初使selenium

热门文章

  1. 2002-11-17梦笔记
  2. 管理感悟:一个人的工作效率是不可能提高的
  3. 申请AppleID的界面,连继续按钮都看不到
  4. LINUX:安装下载源码用的hg
  5. Decorator设计模式(装饰)
  6. JAVA开发做不出来_为什么一道很简单的编程题做不出来?
  7. matlab着重标出某个点,MATLAB与数学实验讲义资料.doc
  8. C# 自定义网格 dataGridView 三角箭头移动 获取当前行列序号 滚动条显示改变 滚动条定位索引
  9. android设计个人简历页面_制作个人简历网站教程
  10. WPF DataGrid使用 后台界面修改前台不刷新问题