express-7 请求和响应对象(2)

摘要:
Lib/快递。js这是一个相对较短的shell,是lib/application.js中Connect的功能扩展。它返回一个可以使用http.createServer运行Express应用程序的函数。Lib/响应。js扩展了http。节点的ServerRepense对象以提供响应对象。响应对象的所有属性和方法都在此文件中。库/路由器/路由。js提供了基本的路由支持。深入学习Express源代码时,可能需要参考Node文档,尤其是HTTP模块;内容渲染###在大多数情况下,res.render用于渲染内容,从而最大程度地根据布局渲染视图。GET节点,返回JSON、XML或textapp。get('/api/tours',函数(req,res){vartoursXml='˂?

获取更多信息###

如果正在寻找某些功能,首先要查看Express的API文档
如果需要的信息没在文档中,有时就不得不深入研究Express源码; 下面是Express源码的路径说明

  • lib/application.js
    Express主接口。如果想了解中间件是如何接入的,或视图是如何被渲染的,可以看这里。

  • lib/express.js
    这是一个相对较短的shell,是lib/application.js中Connect的功能性扩展,它返回一个函数,可以用http.createServer运行Express应用。

  • lib/request.js
    扩展了Node的http.IncomingMessage对象,提供了一个稳健的请求对象。关于请求对象属性和方法的所有信息都在这个文件里。

  • lib/response.js
    扩展了Node的http.ServerReponse对象,提供响应对象。关于响应对象的所有属性和方法都在这个文件里。

  • lib/router/route.js
    提供基础路由支持。尽管路由是应用的核心,但这个文件只有不到200行,你会发现它非常地简单优雅。

  • 在你深入研究Express源码时,或许需要参考Node文档,尤其是HTTP模块部分;

内容渲染###

大多数情况下,渲染内容用res.render,它最大程度地根据布局渲染视图。如果想写一个快速测试页,也许会用到res.send。你可以使用req.query得到查询字符串的值,使用req.session得到会话值,或使用req.cookie/req.singedCookies得到cookies值。

  • 基本用法
//基本用法
app.get('/about', function(req, res){
     res.render('about');
});
  • 200以外的响应代码
app.get('/error', function(req, res){
     res.status(500);
     res.render('error');
});
//或是一行...
app.get('/error', function(req, res){
     res.status(500).render('error');
});
  • 将上下文传递给视图,包括查询字符串、cookie和session值
app.get('/greeting', function(req, res){
    res.render('about', {
        message: 'welcome',
        style: req.query.style,
        userid: req.cookie.userid,
        username: req.session.username,
    });
});
  • 没有布局的视图渲染
//下面的layout没有布局文件,即views/no-layout.handlebars
//必须包含必要的HTML
app.get('/no-layout', function(req, res){
    res.render('no-layout', { layout: null });
});
  • 使用定制布局渲染视图
// 使用布局文件views/layouts/custom.handlebars
app.get('/custom-layout', function(req, res){
    res.render('custom-layout', { layout: 'custom' });
});
  • 渲染纯文本输出
app.get('/test', function(req, res){
    res.type('text/plain');
    res.send('this is a test');
});
  • 添加错误处理程序
//这应该出现在所有路由方法的结尾
//需要注意的是,即使你不需要一个“下一步”方法
//它也必须包含,以便Express将它识别为一个错误处理程序
app.use(function(err, req, res, next){
    console.error(err.stack);
    res.status(500).render('error');
});
  • 添加一个404处理程序
//这应该出现在所有路由方法的结尾
app.use(function(req, res){
    res.status(404).render('not-found');
});

处理表单###

当处理表单时,表单信息一般在req.body中(或者偶尔在req.query中)。可以使用req.xhr来判断是AJAX请求还是浏览请求

  • 基本表单处理
//必须引入中间件body-parser
app.post('/process-contact', function(req, res){
    console.log('Received contact from ' + req.body.name +
         ' <' + req.body.email + '>');
    //保存到数据库....
    res.redirect(303, '/thank-you');
});
  • 更强大的表单处理
//必须引入中间件body-parser
app.post('/process-contact', function(req, res){
    console.log('Received contact from ' + req.body.name +
    ' <' + req.body.email + '>');
    try {
      //保存到数据库....

      return res.xhr ?
          res.render({ success: true }) :
          res.redirect(303, '/thank-you');
    } catch(ex) {
      return res.xhr ?
          res.json({ error: 'Database error.' }) :
          res.redirect(303, '/database-error');
    }
});

提供一个API###

如果提供一个类似于表单处理的API,参数通常会在req.query中,虽然也可以使用req.body。与其他API不同,这种情况下通常会返回JSON、XML或纯文本,而不是HTML。你会经常使用不太常见的HTTP方法,比如PUT、POST和DELETE。

  • “产品”数组(通常是从数据库中检索):
var tours = [
    { id: 0, name: 'Hood River', price: 99.99 },
    { id: 1, name: 'Oregon Coast', price: 149.95 },
];
  • 简单的GET节点,只返回JSON数据
app.get('/api/tours'), function(req, res){
    res.json(tours);
});
  • 根据客户端的首选项,使用Express中的res.format方法对其响应。GET节点,返回JSON、XML或text
app.get('/api/tours', function(req, res){
    var toursXml = '<?xml version="1.0"?><tours>' +
        products.map(function(p){
           return '<tour price="' + p.price +
                 '" id="' + p.id + '">' + p.name + '</tour>';
        }).join('') + '</tours>'';
    var toursText = tours.map(function(p){
           return p.id + ': ' + p.name + ' (' + p.price + ')';
        }).join('
');
   res.format({
            'application/json': function(){
                  res.json(tours);
           },
            'application/xml': function(){
                  res.type('application/xml');
                  res.send(toursXml);
           },
           'text/xml': function(){
                 res.type('text/xml');
                 res.send(toursXml);
           }
          'text/plain': function(){
                 res.type('text/plain');
                 res.send(toursXml);
          }
     });
});
  • PUT节点更新一个产品信息然后返回JSON。参数在查询字符串中传递(路由字符串中的'':id''命令Express在req.params中增加一个id属性)。用于更新的PUT节点
//API用于更新一条数据并且返回JSON;参数在查询字符串中传递 
app.put('/api/tour/:id', function(req, res){
    var p = tours.some(function(p){ return p.id == req.params.id });
    if( p ) {
             if( req.query.name ) p.name = req.query.name;
             if( req.query.price ) p.price = req.query.price;
             res.json({success: true});
    } else {
             res.json({error: 'No such tour exists.'});
    }
});
  • 用于删除的DEL节点
// API用于删除一个产品
api.del('/api/tour/:id', function(req, res){
    var i;
    for( var i=tours.length-1; i>=0; i-- )
        if( tours[i].id == req.params.id ) break;
    if( i>=0 ) {
        tours.splice(i, 1);
        res.json({success: true});
    } else {
        res.json({error: 'No such tour exists.'});
    }
});

免责声明:文章转载自《express-7 请求和响应对象(2)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Android -- TypedArrayNVMe概述下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

UE4 Subsystems

  《InsideUE4》GamePlay架构(十一)Subsystems - 知乎 (zhihu.com) 引言 非常惭愧,自从我更新完GamePlay架构十篇之后,我就断更了许久。如今说再多缘由也是借口,借着假期,在家继续重操旧业,继续写写技术文章。 UE在4.22版本的时候,开始引入Subsystems,然后在4.24完善。写本篇文章的一个原因是S...

API接口之安全篇

APP、前后端分离项目都采用API接口形式与服务器进行数据通信,传输的数据被偷窥、被抓包、被伪造时有发生,那么如何设计一套比较安全的API接口方案呢? 一般的解决方案如下: 1、Token授权认证,防止未授权用户获取数据; 2、时间戳超时机制; 3、URL签名,防止请求参数被篡改; 4、防重放,防止接口被第二次请求,防采集; 5、采用HTTPS通信协议,防...

Django-rest-framework --- 总结

目录 drf回顾总结 drf基础知识点 1.drf框架安装 安装 drf框架规矩的封装风格 drf请求生命周期 2.接口 3.restful接口规范 4.基于restful规范的原生Django接口 主路由:url.py api组件的子路由:api/url.py 模型层:model.py 后台层:admin.py 数据库迁移 视图层:vi...

java 服务接口API限流 Rate Limit

  一、场景描述                                                                                                      很多做服务接口的人或多或少的遇到这样的场景,由于业务应用系统的负载能力有限,为了防止非预期的请求对系统压力过大而拖垮业务应用系统。    ...

Java 9 揭秘(17. Reactive Streams)

Tips做一个终身学习的人。 在本章中,主要介绍以下内容: 什么是流(stream) 响应式流(Reactive Streams)的倡议是什么,以及规范和Java API 响应式流在JDK 中的API以及如何使用它们 如何使用JDK 9中的响应式流的Java API来创建发布者,订阅者和处理者 一. 什么是流 流是由生产者生产并由一个或多个消费者消费...

jdk版本比较

JDK各个版本的新特性   对于很多刚接触java语言的初学者来说,要了解一门语言,最好的方式就是要能从基础的版本进行了解,升级的过程,以及升级的新特性,这样才能循序渐进的学好一门语言。今天先为大家介绍一下JDK1.5版本到JDK1.7版本的特性。希望能给予帮助。 JDK1.5新特性:   1.自动装箱与拆箱: 自动装箱的过程:每当需要一种类型的对...