用node + express搭建一个简单的本地服务端

1,968 阅读5分钟

使用node的http创建一个简单server

我们都知道,用node创建一个简单的本地服务器可以用http模块中的createServer来创建,例如:

//server.js

const http = require('http');

const server = http.createServer((request, response) => {
    response.writeHead(200, {'Content-Type': 'text/html'});
    response.end("This is a server by Node.js");
});

server.listen(1234);

这样子我们就完成了一个http服务器的创建了,使用node server.js开启,然后只要访问http://localhost:1234,就会看到页面上输出:This is a server by Node.js

那么,其实express就是基于node开发出来的一款可以方便我们快速搭建一个server的框架, 关于express的详情内容请前往 www.expressjs.com.cn/ 查看

使用express创建本地server

express的安装

npm install express --save

快速的搭建

//server.js
const express = require('express');
const app = express();
const port = 1234;

app.get('/', (req, res) => {
  res.send('Hello World!')
});

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
});

使用node server.js开启,然后只要访问http://localhost:1234 ,就会看到页面上输出:Hello World!

基础路由

app.METHOD(PATH, HANDLER)

  • app express的实例
  • METHOD 请求方式
  • PATH 请求路径
  • HANDLER 当path匹配时候的回调函数
app.get('/example', (req, res) => {
  res.send({
    message: 'Hello World!'
  })
})
app.post('/user', (req, res) => {
  res.send({
    message: 'Got a POST request'
  })
})
app.put('/user', (req, res) => {
  res.send('Got a PUT request at /user')
})
app.delete('/user', (req, res) => {
  res.send('Got a DELETE request at /user')
})

你可以传入多个callback,但仅限在使用next参数的时候:

app.get('/example', (req, res, next) => {
  console.log('the response will be sent by the next function ...')
  next()
}, (req, res) => {
  res.send('Hello from example!')
})

再比如添加更多callback:

const cb0 = function (req, res, next) {
  console.log('CB0')
  next()
}

const cb1 = function (req, res, next) {
  console.log('CB1')
  next()
}

const cb2 = function (req, res) {
  res.send('Hello from C!')
}

app.get('/example', [cb0, cb1, cb2])

更神奇的是,还可以这样写:

const cb0 = function (req, res, next) {
  console.log('CB0')
  next()
}

const cb1 = function (req, res, next) {
  console.log('CB1')
  next()
}

app.get('/example', [cb0, cb1], function (req, res, next) {
  console.log('the response will be sent by the next function ...')
  next()
}, function (req, res) {
  res.send('Hello from example!')
})

这里有个特殊的函数:app.all(path,function)

app.all('/user',(req, res, next) => {
  res.send('Got a All request at /user'')
})

和get/post等函数不同,app.all()函数可以匹配所有的HTTP请求,也就是说它可以过滤所有路径的请求,如果使用all函数定义中间件,那么就相当于所有请求都必须先通过此该中间件

如下所示,我们使用all函数在请求之前设置响应头属性:

const express = require("express");
const app = express();

app.all("*", function(req, res, next) {
  //设置响应头属性值
  res.writeHead(200, { "Content-Type": "text/html;charset=utf-8" });   
  next();
});

app.get("/", function(req, res) {
  res.send("欢迎来到首页!");
});

app.get("/about", function(req, res) {
  res.send("欢迎来到about页面!");
});

app.get("*", function(req, res) {
  res.send("404 - 未找到!");
});

app.listen(1234);

上面代码参数中的“*”表示对所有路径有效,这个方法在给特定前缀路径或者任意路径上处理时会特别有用,不管我们请求任何路径都会事先经过all函数

express还提供了一个route()方法,你可以在创建一个请求路径后,链式的创建请求:

app.route('/book')
  .get(function (req, res) {
    res.send('Get a random book')
  })
  .post(function (req, res) {
    res.send('Add a book')
  })

中间件

中间件函数是能够访问请求对象(req)、响应对象(res)和应用程序请求-响应周期中的下一个函数的函数。next函数是Express路由器中的一个函数,当它被调用时,执行接替当前中间件的中间件

中间件功能可以执行以下任务:

  • 执行任何代码。
  • 对请求和响应对象进行更改。
  • 结束请求-响应周期。
  • 调用堆栈中的下一个中间件。

我们使用 app.use() 就可以使用中间件函数

下面是一个例子:

const express = require('express');
const app = express();

const requestTime = function (req, res, next) {
  req.requestTime = Date.now();
  next();
};

app.use(requestTime);

app.get('/', function (req, res) {
  const responseText = 'Hello World!<br>';
  responseText += '<small>Requested at: ' + req.requestTime + '</small>';
  res.send(responseText);
});

app.listen(3000);

以上例子,利用中间件函数,对请求对象进行了修改,设置了请求对象的requestTime属性,这样,在调用get请求的时候,请求对象req中就有了requestTime属性

这里有一些实用的中间件 www.expressjs.com.cn/resources/m…

express托管静态文件

如果需要将一些例如css文件,图片,html文件等静态公开,使他人可以访问这些静态资源,则需要使用:

express.static(root, [options])

这是express内置的中间件函数

例如,通过如下代码就可以将 public 目录下的图片、CSS 文件、JavaScript 文件对外开放访问了:

app.use(express.static('public'));

现在,你就可以访问 public 目录中的所有文件了:

http://localhost:1234/images/kitten.jpg
http://localhost:1234/css/style.css
http://localhost:1234/js/app.js
http://localhost:1234/images/bg.png
http://localhost:1234/hello.html

如果要使用多个静态资源目录,请多次调用 express.static 中间件函数:

app.use(express.static('public'));
app.use(express.static('files'));

创建一个虚拟路径来访问public目录中的文件,虚拟路径本身不存在系统文件目录中:

app.use('/static', express.static('public'));

现在,你就可以通过带有 /static 前缀地址来访问 public 目录中的文件了:

http://localhost:1234/static/images/kitten.jpg
http://localhost:1234/static/css/style.css
http://localhost:1234/static/js/app.js
http://localhost:1234/static/images/bg.png
http://localhost:1234/static/hello.html

当然,文件路径也需要根据实际情况做一定处理:

app.use('/static', express.static(path.join(__dirname, 'public')));

使用express处理跨域问题

这是一个在node中处理跨域的最简单实现:

const express = require('express');
const app = express();
const bodyParser = require('body-parser');

//处理接收request对象的大小限制
app.use(bodyParser.json({
  limit: '50mb'
}));

//处理接收request对象的大小限制
app.use(bodyParser.urlencoded({
  limit: '50mb',
  parameterLimit: 100000,
  extended: true 
}));

app.all("/*", function(req, res, next) {
  // 跨域处理
  res.header("Access-Control-Allow-Origin", "*");
  res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length,   Authorization, Accept, X-Requested-With , yourHeaderFeild');
  res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
  res.header("X-Powered-By", ' 3.2.1');
  res.header("Content-Type", "application/json;charset=utf-8");
  next(); // 执行下一个路由
});

app.get("/home", function(req, res) {
  res.send("欢迎来到首页!");
});

app.listen(8787,()=>{
  console.log('服务端开启在8787端口');
});