当前位置: 首页 > 后端技术 > Node.js

Express实战(一):概述

时间:2023-04-03 12:33:00 Node.js

在正式学习Express的内容之前,我们有必要对Node.js有个大了解。很长一段时间,JavaScript是一种用于编写在浏览器中运行的脚本的语言。然而近年来,随着互联网的发展和技术的进步,JavaScript迎来了集中爆发的时代。一个标准事件是2009年Node.js的诞生。Node.js是从GoogleChrome的V8引擎发展而来的,它使JavaScript可以在服务器端运行。这极大地扩展了JavaScript的应用场景,使JavaScript全栈成为热门话题。开发者不再需要学习Ruby、Python、Java等语言和框架,仅依靠JavaScript即可完成大部分前后端开发任务。虽然JavaScript在某些方面并不完美,甚至存在一些设计缺陷,但这并不影响Nodejs的流行。V8引擎的快速处理能力和异步编程风格将开发人员从多线程中解放出来。其中,前后端相同的技术栈可以说是其最大的杀手锏。日益丰富的生态环境也吸引了越来越多开发者对JavaScript的关注,使用Node.js进行开发已经成为一件非常时髦的事情。与浏览器环境中的JavaScript一样,Node.js仅提供构建应用程序所需的低级接口和功能。这些低级接口通常冗长且难以使用。所以有人在Node.js之上实现了Express框架。它的基本概念类似于jQuery。通过封装底层接口,在提供更高层接口的同时简化了代码。此外,Express的可扩展性也很强。框架本身与程序的架构和业务无关,也可以通过第三方库进行功能扩展。Node.js应用场景Node.js(通常简称为Node)是一个JavaScript代码运行平台。虽然JavaScript在大多数情况下是运行在浏览器中的,但是并没有任何地方规定它只能运行在浏览器中。作为一种编程语言,它在本质上与Ruby、Python、C++、PHP并无区别。就像您可以使用pythonmyfile.py来运行Python脚本一样,您可以使用nodemyfile.js来执行JavaScript程序。但是在服务端开发中,Node有哪些值得我们去尝试的优势呢?首先,Node.js的JavaScript引擎非常快。毕竟,它基于谷歌浏览器著名的快速V8引擎,每秒可以执行数千条JavaScript指令。其次,Node.js通过异步编程范式充分发挥其高并发能力。与现实生活中的烘焙类比再好不过了。假设我需要做一些松饼,那么首先我需要准备好面粉。这个时候,我就离不开做其他事情了。但是,一旦我将松饼放入烤箱,我就可以离开并做其他事情而无需等待。在Node.js中,客户端可以随时向服务器发送请求。有可能在您处理一个请求的同时,客户端也发送了另一个请求。假设,两个请求都需要访问数据库。然后可以在第一个请求执行数据库操作的时候切换到第二个请求。虽然我们不能同时响应两者,但是我们可以使用异步的方式来跳过等待耗时操作的结果,直接处理后续的请求。而其他一些运行环境默认是没有这个能力的。例如,RubyonRails一次只能处理一个请求。如果要提高程序的并发度,那么就需要购买更多的服务器。下图可以清楚地看出两者的区别:与同步方式相比,异步处理的效率明显更高,虽然异步代码不是并行处理的。当然,这并不是说异步处理让Node.js成为世界上最快的语言之一。尽管Node.js可以最大限度地发挥单核CPU的性能,但它仍然比不上多核的处理能力。其他语言允许您利用多核能力同时执行多项任务。和之前的烘焙一样:你可以购买更多的烤箱来同时烘焙更多的饼干。Node开始支持此功能,但它并不像在其他语言中那么重要。就个人而言,我选择Node.js是因为性能不是最重要的原因,尽管它确实比Ruby、Python和其他脚本语言快。最大的原因是它使用同一种语言进行前后端开发。通常,您会在编写Web应用程序时使用JavaScript。但是在Node.js出现之前,前端和后端开发必须使用不同的语言来完成。为此你需要学习多种语言和框架。有了Node.js,你可以在前后端开发中使用一种语言自由切换,这是最吸引人的地方。什么是快递?Express是基于Node.js封装的上层服务框架,提供更简洁的API和更实用的新功能。通过中间件和路由使程序的组织和管理更容易;它提供了丰富的HTTP工具;它使动态视图渲染更容易;它还定义了一组可扩展的标准。Node.js的功能通过简单的JavaScript函数,您可以使用Node.js创建Web应用程序。该函数用于监听浏览器或其他设备发起的网络请求。当接收到一个请求时,该函数会分析请求的内容并做出相应的处理。例如,当您请求站点的主页时,该函数将知道您的意图并呈现主页的HTML。如果请求API接口,函数会返回相应的JSON数据给客户端。假设服务器需要向用户返回当前时间和时区信息,程序一般包括以下功能:如果客户端发起主页请求,Web应用程序将返回一个包含所需信息的HTML。如果客户端访问地址错误,Web应用程序将返回HTTP404错误以及错误描述。如果不使用Express,直接在Node.js上构建应用,完整的流程图大致如下:上述过程中,开发者只需要关注画圈部分的处理即可。用于处理浏览器请求的JavaScript函数称为请求处理程序。它也只是一个处理请求和响应的JavaScript函数,没有什么特别之处。Node.js的HTTP服务会接管网络连接,所以你不需要关注和处理复杂的网络协议内容。从代码上看,这个函数包含两个参数:一个是网络请求的request对象,一个是代表网络响应的response对象。在上次信息应用中,请求处理函数会检查请求URL。如果请求是针对主页,则返回成功的响应页面。否则,返回404错误。没有Node.js应用程序以这种方式处理它:编写处理函数来响应请求非常简单。问题是Node.jsAPI对开发人员不是很友好。例如,如果我们要发送一张JPEG图片,可能至少需要45行代码。创建可重用的HTML模板更加复杂。此外,虽然功能强大,但Node.js的HTTP模块仍然缺少一些有用的功能。Express的出现就是为了解决这些问题,让你高效的使用Node.js来编写Web应用。Express给Node.js带来了什么?从大的角度来看,Express为Node.js的HTTP模块带来了两大特性:它通过提供大量易于使用的接口来简化程序的复杂性。例如,为了缓解上面的JPEG图片问题,Express可以将代码压缩到一行。它允许拆分请求处理程序,将其重构为许多负责特定请求的小请求处理程序。这有利于模块化和后期维护。与上图相比,下图是Express处理请求的大致流程:和之前一样,开发者只需要关注圆圈的内容即可。虽然图看起来比以前复杂了,但实际开发起来更简单了。本质上,它主要做了两件事:不同于之前的大请求处理函数,这里使用了大量的小处理函数。有些功能每次都会执行(例如,请求日志),有些功能只在特定情况下触发(例如,404错误)。Express有很多工具可以用来区分这些处理程序。请求处理函数中有两个参数:请求和响应。Node的HTTP可以对它做一些基本的处理,例如:获取浏览器的user-agent。Express比较强大,可以获取访问者的IP地址,解析优化后的URL请求对象。响应对象也得到了增强。使用sendFile等函数将文件传输代码压缩到一行。这极大地简化了处理函数的功能实现。利用Express提供的简洁的API接口,通过编写小的请求处理函数,可以大大压缩代码量,提高开发效率。Express的最小化概念Express虽然是一个框架,但是它的编程规范非常灵活。您可以使用它编写各种类型的应用程序,从视频聊天到个人博客等等。另外,Express本身并不是百宝箱,在实际开发中可能需要用到大量的第三方库。这些库可以帮助你解决一些小问题,让你可以专注于那些重要的问题,进而发扬Unix的do-one-thing-well把事情做好的哲学。但这种极简主义哲学也是一把双刃剑。一方面,Express非常灵活可靠,不会引入不必要的垃圾代码。另一方面,与其他框架相比,这种简单性不可避免地导致缺乏功能。这意味着要在程序架构上多做功课,出问题时花时间寻找第三方模块。它有点开箱即用。有些人喜欢灵活的框架,而另一些人喜欢结构固定的。例如,PayPal也使用Express,但有严格的规范来约束其开发人员。Express本身并不注重程序架构,因此程序员可以根据自己的喜好进行选择。由于你对程序有绝对的控制权,一旦做出了不明智的决定,你就可以慢慢爬后面的坑了。大型和小型框架的优缺点从来没有正确答案,所以不要太在意它们。在这里,我只想让你记住Express是一个最小的框架。ExpressExpress的核心非常简洁,Node.js的封装效果也非常好,而这一切都来自于框架中的四大设计。中间件如前所述,原生Node.js对所有请求和响应使用请求处理函数。中间件不是一个好听的名字,但这个词并不是Express独有的,相反它已经存在了很长时间。这个概念非常简单:我们组合了一系列简单的处理程序,而不是一个巨大的请求处理程序。每个小处理函数对应一个小任务,这些处理函数称为中间件。中间件可以处理各种任务,从记录请求到发送静态文件再到设置HTTP标头。例如,应用程序中使用的第一个中间件功能可能是使用logger-log记录服务器中的每个请求。日志记录完成后,它会继续调用链中的下一个中间件。下一个中间件功能可能会去验证用户。如果权限不够,会提示“未授权”。否则继续执行下一个中间件。此时中间件的功能可能是渲染首页,结束响应。下图演示了这两种情况:从图中可以看出,日志中间件是最先执行的,肯定会被执行。接下来是执行授权认证的中间件。如果满足用户权限,则继续执行下一个中间件,否则不执行后面的中间件。中间件最大的特点就是比较标准,这也意味着开发者可以通过为Express开发中间件来扩展其功能。同时,这可能意味着一些通用的中间件可能已经开发出来,比如LESS、SCSS等静态文件的编译、权限控制、cookies和session的解析等。路由显然比中间件好。与中间价类似,路由拆分了请求处理功能。不同的是,路由是根据请求的URL和HTTP方法来决定处理方式的。例如,假设您的应用程序中有一个主页和一个留言簿页面。当用户使用GET请求首页时,Express会返回对应的首页内容。对留言板的请求的处理也是如此。如果用户通过POST方式在留言板页面留言,路由需要做相应的处理,刷新页面。与中间件类似,上述路由的处理也是通过处理函数来定义的。而不同的行为会调用不同的处理函数。Express中的中间件和路由是相辅相成的。例如:您可以在响应主页路由时记录请求。子应用程序Express应用程序通常很小,甚至只有一个文件。随着应用程序规模的扩大,您可能会将其拆分为多个文件和文件夹。虽然Express对于应用规模的增长并没有明确的指导方针。但是我们可以用子应用程序的重要特性来回应。这些应用程序在Express术语中也称为路由器。通过实现正常大小的路由器子应用程序,可以将大型应用程序拆分为模块。您甚至可以更详细地拆分一些子应用程序。比如应用中可能有管理后台、单页应用、API接口等几个子模块。此时,您可以将这些子模块实现为子应用程序。具体如下:当程序规模变大时,这个特性的优势就会逐渐显现出来。简单易用的API函数Express由中间件和路由组成,其中需要编写大量的异步处理函数来实现相关功能。为了让处理更加高效和正确,Express在原生Node.js的基础上进行了大量的封装。在压缩代码量提高效率的同时,也降低了人为出错的概率。除了发送文件,Express提供的HTML渲染功能也是原生Node.js所望尘莫及的。此外,Express在请求解析方面也做了很多工作。与以前的功能不同,这些易于使用的功能在保持强大功能的同时不会对应用程序产生负面影响。Express生态系统与其他工具一样,Express并不孤单。它生存在Node.js生态中,所以你可以找到大量的第三方模块来提高你的开发效率,比如数据库连接驱动。因为Express具有极强的可扩展性,所以在整个生态系统中有大量为Express开发的类库。将Express与其他框架进行比较Express既不是第一个也不会是最后一个Web框架。同样,Express并不是Node.js生态系统中唯一的框架。它最大的竞争对手可能是Hapi.js。和Express类似,它也有路由和中间件的概念。但不同的是,它没有基于Node.js的HTTP模块来处理网络请求,而是Walmart开发的网络模块。该模块已被Mozilla、OpenTable和NPM接受,并在实际程序中进行了测试。作为Express最大的竞争对手,我怀疑双方的开发者之间可能存在很大的仇恨。Node.js世界中最流行的大型框架是全栈Meteor。与自由灵活的Express相比,Metero具有非常严格的程序结构。与Express只专注于HTTP层的处理不同,Meteor作为一个全栈框架,可以同时运行在客户端和服务端。当然,这只是一种设计选择,很难说谁更好。类似于Express基于Node.js的封装,Express也有更高级的封装。例如,由PayPal创建的Kraken。虽然从技术角度来看,Kraken只是Express的一个中间件。不过,它还是做了很多事情,比如:中间件的安全绑定。Sails.js是另一个基于Express的新框架,具有内置数据库、WebSocket集成、API生成等功能。这些框架都是Express相对固定的封装实现。Express的主要特性之一是中间件。Connect是一个Node.js和纯中间件框架。它不提供路由和易于使用的功能接口。而Express曾经在其中间件层使用Connect。虽然现在已弃用,但Express中间件始终与Connect中间件完全兼容。这意味着快车的火力得到了极大的提升。除了上面提到的那些之外,还有许多用其他语言实现的Web框架。Express的很多灵感来自于Ruby世界中的轻量级Web框架Sinatra。和Express类似,Sinatra中也有路由和中间件功能。Sinatra框架的思想被许多其他语言借鉴并重新实现。如果你用过这类框架,你一定对Express不陌生。当然,Express也借鉴了Python中的Bottle和Flask框架。相应地,Express与Django、RubyonRails、ASP.NET等框架之间也存在着巨大的差距。这些框架非常庞大,程序结构也比固定的功能丰富。此外,Express与PHP有很大不同,两者都在服务上运行,但后者与HTML紧密耦合。Express只是服务器端Web框架中的一种,因此我们不能在这里说Express肯定优于其他框架。它有一些独特的特性,比如Node.js的性能和前后端统一的语言。但同时,它的功能也远不及其他框架,JavaScript也不是广大开发者公认的“好”语言。脱离具体场景讨论优缺点是没有意义的。下面我们来看看Express的一些适用场景。Express应用场景理论上,Express可以用来构建任何Web应用程序。响应所有请求也可以通过上面提到的框架来完成。那么,为什么选择快递?最大的好处是,用Node.js写的JavaScript可以在浏览器和客户端之间共享。从代码重用的角度来看,这种情况是很理想的。从心理学的角度来说也是非常有用的,开发的时候不需要在服务端模式和客户端模式之间切换。前端开发人员无需学习新语言即可直接编写后端代码。当然,前端开发者还是需要学习一些新内容的,否则这本书就没有必要了。Express可以帮助您做到这一点,人们为这个堆栈创造了一个名字:MEAN。就像“LAMP”代表Linux、Apache、MySQL和PHP,“MEAN”代表MongoDB、Express、Angular和Node.js。人们喜欢它是因为它是一个纯JavaScript堆栈。Express通常用于驱动单页应用程序(SPA)。SPA在前端严重依赖JavaScript,并且通常需要服务器组件。大多数服务器只需要提供HTML、CSS和JavaScript,但有时RESTAPI也是一项常见需求。Express可以做到这两点,服务于HTML并非常适合构建API。Express相对较低的学习曲线允许前端开发人员构建几乎没有新内容的SPA服务。当你使用Express写应用程序时,确定你必须使用MEAN技术栈的E和N部分,如果对其他两个Express没有限制,你可以使用不同的解决方案。例如,可以用Backbone.js替代Angular,形成MEBN技术栈。用SQL替换MongoDB,形成SEAN技术栈。虽然MEAN术语很常见并且配置也很流行,但您可以根据自己的需要做出自己的选择。我们将在本书中涵盖的技术栈是MEN:MongoDB、Express和Node.js。此外Express还具有一些实时特性。在其他语言支持WebSocket和WebRTC的同时,Node.js似乎更强一些。这意味着您可以将这些功能应用于Express程序。因为Node.js能做的,Express能做的很多。Node.js和Express的第三方模块社区有大量的模块可以在Express中使用。有些是Express独有的,这些模块与路由和中间件功能高度兼容。其他非专属模块也可以提升Express应用的开发体验和程序性能。如果你有使用过ERB、Jinja2、HAML等模板引擎的经验,你会发现Express的内置函数在渲染HTML方面简直弱爆了。幸运的是,Express也可以使用EJS和Jade等社区模板引擎来解决这个问题。另外,Express本身不支持数据库。您可以通过文件、关系数据库或其他机制来实现数据存储。不过后面会介绍如何在Express中通过Mongoose调用MongoDB数据库。需要注意的一件事:没有Express模块这样的东西,所以第三方库是Node.js模块。Node.js模块兼容并使用Express。所有这些块都是在npm存储库中注册的JavaScript代码块,可以使用一致的方法安装。与在其他环境中一样,模块可以相互依赖,不同的模块可以相互协作。此外,Express只是Node.js中的一个模块。HelloWorld每次学习新的内容,大部分都是从HelloWorld开始的。那么现在让我们看看如何使用Express构建一个简单的HelloWorld项目。不要太在意代码的细节,后面会详细介绍。代码如下:varexpress=require("express");#Avarapp=express();#Bapp.get("/",function(request,response){#Cresponse.send("Helloworld!");#C});#cApp.Listen(3000,Function(){#dConsole.log("ExpressAppStartedonPort3000.");#d});#da:导入Express模块并创建一个新变量。B:创建一个app应用程序C:设置对Root路由的访问,并将响应设置为“Helloworld!”。D:设置程序监听的端口,win提示服务启动成功。再次提醒,看不懂所有代码也没关系,后面会有更详细的讲解。您很快就会了解有关Express的所有知识。总结本文主要介绍:Node.js可以编写web应用,但是开发过程效率不高。Express优雅地解决了这些问题。快递虽小但也很灵活。Express有几个关键特性:中间件将程序处理拆分并按顺序和链式执行。路由也会对程序进行拆分,根据规则对不同的访问请求做出不同的响应。子项目可以实现大Express的拆分,提高可读性,方便后期维护。Express中的大部分代码都需要编写处理函数,Express为此提供了大量简单易用的API。原地址