简介
nodejs 作为一个优良的异步 IO 框架,其自身就是用来作为 http web 服务器应用的,nodejs 中的 http 模块,提供了很多十分有用的 http 相干的性能。
尽管 nodejs 曾经带有 http 的解决模块,然而对于古代 web 应用程序来说,这或者还不太够,于是咱们有了 express 框架,来对 nodejs 的内容进行扩大。
明天咱们将会介绍一下应用 nodejs 和 express 来开发 web 应用程序的区别。
应用 nodejs 搭建 HTTP web 服务
nodejs 提供了 http 模块,咱们能够很不便的应用 http 模块来创立一个 web 服务:
const http = require('http')
const hostname = '127.0.0.1'
const port = 3000
const server = http.createServer((req, res) => {
res.statusCode = 200
res.setHeader('Content-Type', 'text/plain')
res.end('welcome to www.flydean.com\n')
})
server.listen(port, hostname, () => {console.log(`please visit http://${hostname}:${port}/`)
})
下面创立的 http 服务监听在 3000 端口。咱们通过应用 createServer 办法来创立这个 http 服务。
该办法承受一个 callback 函数,函数的两个参数别离是 req (http.IncomingMessage 对象)和一个 res(http.ServerResponse 对像)。
在下面的例子中,咱们在 response 中设置了 header 和 body 值,并且以一个 end 办法来完结 response。
申请 nodejs 服务
咱们创立好 http web 服务之后,个别状况下是从 web 浏览器端进行拜访和调用。然而咱们有时候也须要从 nodejs 后端服务中调用第三方利用的 http 接口,上面的例子将会展现如何应用 nodejs 来调用 http 服务。
先看一个最简略的 get 申请:
const http = require('http')
const options = {
hostname: 'www.flydean.com',
port: 80,
path: '/',
method: 'GET'
}
const req = http.request(options, res => {console.log(`status code: ${res.statusCode}`)
res.on('data', d => {console.log(d);
})
})
req.on('error', error => {console.error(error)
})
req.end()
下面代码咱们应用了 http.request 来创立一个 request,并且传入了咱们自带的 options 参数。
咱们通过 res 的回调事件来进行相应的解决。
再看一个简略的 post 申请:
const http = require('http')
const data = JSON.stringify({name: 'flydean'})
const options = {
hostname: 'www.flydean.com',
port: 80,
path: '/',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length
}
}
const req = http.request(options, res => {console.log(`status code: ${res.statusCode}`)
res.on('data', d => {console.log(d);
})
})
req.on('error', error => {console.error(error)
})
req.write(data)
req.end()
post 和 get 类似,不同的是 options 中的 method 不一样,同时 put 能够有多种申请类型,所以咱们须要在 headers 中指定。
同样的,PUT 和 DELETE 也能够应用同样的形式来调用。
第三方 lib 申请 post
间接应用 nodejs 底层的 http.request 有点简单,咱们须要本人构建 options,如果应用第三方库,比方 axios 能够让 post 申请变得更加简略:
const axios = require('axios')
axios
.post('http://www.flydean.com', {name: 'flydean'})
.then(res => {console.log(`status code: ${res.statusCode}`)
console.log(res)
})
.catch(error => {console.error(error)
})
下面的例子中,咱们间接应用 axios 的 post 申请,并将申请后果封存成了 promise,而后通过 then 和 catch 来进行相应数据的解决。十分的不便。
获取 http 申请的注释
在下面的例子中,咱们通过监听 req 的 data 事件来输入 http 申请的注释:
res.on('data', d => {console.log(d);
})
})
这样做其实是有问题的,并不一定可能取得残缺的 http 申请的注释。
因为 res 的 on data 事件是在服务器取得 http 申请头的时候触发的,这个时候申请的注释可能还没有传输实现,换句话说,申请回调中的 request 是一个流对象。
咱们须要这样解决:
const server = http.createServer((req, res) => {let data = []
req.on('data', chunk => {data.push(chunk)
})
req.on('end', () => {console.log(JSON.parse(data));
})
})
当每次触发 data 事件的时候,咱们将承受到的值 push 到一个数组外面,等所有的值都接管结束,触发 end 事件的时候,再对立进行输入。
这样解决显然有点麻烦。
咱们介绍一个在 express 框架中的简略办法,应用 body-parser 模块:
const bodyParser = require('body-parser')
app.use(
bodyParser.urlencoded({extended: true})
)
app.use(bodyParser.json())
app.post('/', (req, res) => {console.log(req.body)
})
下面的例子中,body-parser 对 req 进行了封装,咱们只用关注与最初的后果即可。
Express 和应用 express 搭建 http web 服务
express 是什么呢?
express 是基于 Node.js 平台,疾速、凋谢、极简的 web 开发框架。它提供一系列弱小的个性,帮忙你创立各种 Web 和挪动设施利用。
丰盛的 HTTP 快捷办法和任意排列组合的 Connect 中间件,让你创立强壮、敌对的 API 变得既疾速又简略。
Express 不对 Node.js 已有的个性进行二次形象,咱们只是在它之上扩大了 Web 利用所需的基本功能。
express helloworld
咱们看一下怎么应用 Express 来搭建一个 helloworld:
var express = require('express');
var app = express();
app.get('/', function (req, res) {res.send('Hello World!');
});
var server = app.listen(3000, function () {var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
简略的应用 app.listen 即可搭建好一个 http web 服务。
express 路由
有了 web 服务,咱们须要对不同的申请门路和申请形式进行不同的解决,这时候就须要应用到了 express 路由性能:
// 对网站首页的拜访返回 "Hello World!" 字样
app.get('/', function (req, res) {res.send('Hello World!');});
// 网站首页承受 POST 申请
app.post('/', function (req, res) {res.send('Got a POST request');});
// /user 节点承受 PUT 申请
app.put('/user', function (req, res) {res.send('Got a PUT request at /user');});
// /user 节点承受 DELETE 申请
app.delete('/user', function (req, res) {res.send('Got a DELETE request at /user');});
更高级一点的,咱们还能够在申请门路中做路由匹配:
// 匹配 acd 和 abcd
app.get('/ab?cd', function(req, res) {res.send('ab?cd');});
// 匹配 abcd、abbcd、abbbcd 等
app.get('/ab+cd', function(req, res) {res.send('ab+cd');
});
// 匹配 abcd、abxcd、abRABDOMcd、ab123cd 等
app.get('/ab*cd', function(req, res) {res.send('ab*cd');
});
// 匹配 /abe 和 /abcde
app.get('/ab(cd)?e', function(req, res) {res.send('ab(cd)?e');});
// 匹配任何门路中含有 a 的门路:app.get(/a/, function(req, res) {res.send('/a/');
});
// 匹配 butterfly、dragonfly,不匹配 butterflyman、dragonfly man 等
app.get(/.*fly$/, function(req, res) {res.send('/.*fly$/');
});
Express 路由句柄中间件
有时候,一个申请可能有多个处理器,express 提供了路由句柄(中间件)的性能,咱们可自由组合处理程序。
留神,在路由句柄中,咱们须要调用 next 办法,来触发下一个路由办法。
var cb0 = function (req, res, next) {console.log('CB0');
next();}
var cb1 = function (req, res, next) {console.log('CB1');
next();}
app.get('/example/d', [cb0, cb1], function (req, res, next) {console.log('response will be sent by the next function ...');
next();}, function (req, res) {res.send('Hello from D!');
});
下面的申请会通过 cb0,cb1 和自定义的两个 function,最终完结。
Express 响应办法
express 提供了很多响应办法 API,能够不便咱们的代码编写:
办法 | 形容 |
---|---|
res.download() | 提醒下载文件。 |
res.end() | 终结响应解决流程。 |
res.json() | 发送一个 JSON 格局的响应。 |
res.jsonp() | 发送一个反对 JSONP 的 JSON 格局的响应。 |
res.redirect() | 重定向申请。 |
res.render() | 渲染视图模板。 |
res.send() | 发送各种类型的响应。 |
res.sendFile | 以八位字节流的模式发送文件。 |
res.sendStatus() | 设置响应状态代码,并将其以字符串模式作为响应体的一部分发送。 |
Express 的动态资源
通常来说,动态资源是不须要服务端进行解决的,在 express 中,能够应用 express.static 来指定动态资源的门路:
app.use(express.static('public'));
当初,public 目录上面的文件就能够拜访了。http://localhost:3000/images/kitten.jpg
http://localhost:3000/css/style.css
http://localhost:3000/js/app.js
http://localhost:3000/images/bg.png
http://localhost:3000/hello.html
// 多个动态资源目录
app.use(express.static('public'));
app.use(express.static('files'));
// 动态前缀
app.use('/static', express.static('public'));
http://localhost:3000/static/images/kitten.jpg
http://localhost:3000/static/css/style.css
Express 应用模板引擎
web 利用当然须要 html 文件,express 中能够应用多种模板语言,让编写 html 页面更加容易。如果想要应用模板引擎。咱们能够应用上面的步骤:
- views, 放模板文件的目录,比方:app.set(‘views’, ‘./views’)
- view engine, 模板引擎,比方:app.set(‘view engine’, ‘jade’)
- 在 views 目录下生成名为 index.jade 的 Jade 模板文件,内容如下:
html
head
title!= title
body
h1!= message
- 在 nodejs 服务端配置 route 规定
// 配置 route 规定
app.get('/', function (req, res) {res.render('index', { title: 'Hey', message: 'Hello there!'});
});
总结
nodejs 和 express 是十分不便的 http web 服务框架,心愿大家可能喜爱。
本文作者:flydean 程序那些事
本文链接:http://www.flydean.com/nodejs-http-express/
本文起源:flydean 的博客
欢送关注我的公众号:「程序那些事」最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!