简介

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 = 3000const 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 和 abcdapp.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 和 /abcdeapp.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.jpghttp://localhost:3000/css/style.csshttp://localhost:3000/js/app.jshttp://localhost:3000/images/bg.pnghttp://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.jpghttp://localhost:3000/static/css/style.css

Express 应用模板引擎

web利用当然须要html文件,express中能够应用多种模板语言,让编写html页面更加容易。如果想要应用模板引擎。咱们能够应用上面的步骤:

  1. views, 放模板文件的目录,比方: app.set('views', './views')
  2. view engine, 模板引擎,比方: app.set('view engine', 'jade')
  3. 在 views 目录下生成名为 index.jade 的 Jade 模板文件,内容如下:
html  head    title!= title  body    h1!= message
  1. 在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的博客

欢送关注我的公众号:「程序那些事」最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!