本文转载自:众成翻译
译者:网络埋伏纪事
链接:http://www.zcfy.cc/article/1750
原文:https://blog.risingstack.com/your-first-node-js-http-server/
本章我会指导你启动一个简单的 Node.js HTTP 服务器,并开始为请求服务。
Node.js 服务器的 http 模块
当开始在 Node.js 中构建基于 HTTP 的应用程序时,内置的 http
/https
模块就是你要与之交互的模块。
现在,我们开始创建第一个 Node.js HTTP 服务器!我们将 require http
模块,并将服务器绑定到 3000
端口来监听。
// index.js 的内容
const http = require('http')
const port = 3000
const requestHandler = (request, response) => {
console.log(request.url)
response.end('Hello Node.js Server!')
}
const server = http.createServer(requestHandler)
server.listen(port, (err) => {
if (err) {
return console.log('something bad happened', err)
}
console.log(`server is listening on ${port}`)
})
可以用如下命令启动:
$ node index.js
这里要注意:
requestHandler
: 每次请求到达服务器时,该函数都会被调用。如果从浏览器访问localhost:3000
,就会出现两条日志信息:一条是/
,一条是favicon.ico
。if (err)
: 错误处理 - 如果端口已被占用,或者服务器因为其它原因不能启动,就会在这里得到通知
http
模块是很低层的 - 用上面的代码片段创建复杂的 Web 应用程序是很耗时间的。这就是为什么我们经常会为项目选用一个框架的原因。有很多框架可以选,但是最重要的是这些:
本章和下一章我们打算用 Express,因为在 NPM 上可以找到的 Express 模块最多。
Express
快速、开放、极简的 Node.js Web 框架 - http://expressjs.com/
将 Express 添加到项目中的唯一方法是 NPM 安装:
$ npm install express --save
安装完 Express 后,我们来看看如何创建一个像以前那样的应用程序:
const express = require('express')
const app = express()
const port = 3000
app.get('/', (request, response) => {
response.send('Hello from Express!')
})
app.listen(port, (err) => {
if (err) {
return console.log('something bad happened', err)
}
console.log('server is listening on ${port}')
})
这里你必须注意到的最大区别是,Express 默认给了一个路由器。不需要手动检测 URL 来判断要做什么,而是用 app.get
、app.post
、app.put
等定义应用程序的路由。它们会被翻译为对应的 HTTP 动词。
Express 实现的最强大概念之一是中间件模式。
中间件
可以把中间件当作是 Unix 管道,但是是对 HTTP 请求的管道。
在图中你可以看到一个请求是如何通过 Express 应用程序的。它经历了三个中间件。每个中间件都可以修改它,然后基于业务逻辑,要么第三个中间件送回一个响应,要么将它送到一个路由处理器。
在实践中,可以按这种方式做:
const express = require('express')
const app = express()
app.use((request, response, next) => {
console.log(request.headers)
next()
})
app.use((request, response, next) => {
request.chance = Math.random()
next()
})
app.get('/', (request, response) => {
response.json({
chance: request.chance
})
})
app.listen(3000)
这里要注意:
app.use
: 在这里定义中间件 - 它带有三个参数的函数,第一个是请求,第二个是响应,第三个是next
回调。调用next
就是通知 Express 可以跳到下一个中间件,或者路由处理器。第一个中间件只是记录请求头,然后立即调用下一个。
第二个中间件给请求添加一个特殊属性 - 这是中间件模式最强大的功能之一。你的中间件可以向 request 对象添加额外的数据,这个数据可以被下游中间件读取或修改。
错误处理
在所有框架中,正确的错误处理是至关重要的。在 Express 中,必须创建特殊的中间件函数来实现 - 一个带有四个参数的中间件:
const express = require('express')
const app = express()
app.get('/', (request, response) => {
throw new Error('oops')
})
app.use((err, request, response, next) => {
// log the error, for now just console.log
console.log(err)
response.status(500).send('Something broke!')
})
这里要注意:
错误处理函数应该是用
app.use
添加的最后一个函数。错误处理器有一个
next
回调 - 它可以用来将多个错误处理器链在一起。
渲染 HTML
至此,我们已经了解了如何发送 JSON 响应 - 是时候学习如何用简单方法渲染 HTML 了。为此,我们要使用 express-handlebars 中的 handlebars 包。
首先,创建如下的目录结构:
├── index.js
└── views
├── home.hbs
└── layouts
└── main.hbs
之后,用如下代码片段填充 index.js
:
// index.js
const path = require('path')
const express = require('express')
const exphbs = require('express-handlebars')
const app = express()
app.engine('.hbs', exphbs({
defaultLayout: 'main',
extname: '.hbs',
layoutsDir: path.join(__dirname, 'views/layouts')
}))
app.set('view engine', '.hbs')
app.set('views', path.join(__dirname, 'views'))
上述代码初始化 handlebars
引擎,将布局目录设置为 views/layouts
。布局将会存在这个目录中。
设置好后,可以把初始 html
放进 main.hbs
中 - 为保持简单,我们就用这个:
<html>
<head>
<title>Express handlebars</title>
</head>
<body>
{{{body}}}
</body>
</html>
这里的 {{{body}}}
占位符,就是放内容的地方 - 下面我们创建 home.hbs
!
<h2>Hello {{name}}<h2>
要让它起作用,我们得做最后一件事情:给 Express 应用程序添加一个路由处理器:
app.get('/', (request, response) => {
response.render('home', {
name: 'John'
})
})
render
方法带有两个参数:
第一个是视图的名称;
第二个是要渲染的数据。
一旦调用这个端点,会得到如下的 HTML:
<html>
<head>
<title>Express handlebars</title>
</head>
<body>
<h2>Hello John<h2>
</body>
</html>
这只是冰山一角 - 要学习如何添加更多布局甚至局部模板,请参考官方 express-handlebars 文档。
调试 Express
在某些情况下,你可能需要看到应用程序正在运行时 Express 发生了什么。为此,可以传递如下环境变量给 Express:DEBUG=express*
。
必须用如下方式启动 Node.js HTTP 服务器:
$ DEBUG=express* node index.js
总结
本章学习了如何从头开始创建第一个 Node.js HTTP 服务器。我推荐用 Express 开始,然后随意去尝试。
下章会学习如何从数据库获取信息。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。