express框架的基本使用

express框架的基本使用

1、express介绍

express是基于Node.js平台的极简、灵活的WEB应用开发框架。简单来说,express就是一个封装好的工具包,封装了很多功能,便于开发WEB应用(HTTP服务)

2、express使用

2.1、express下载

npm i express

// 导入
const express = require('express');

// 创建应用对象
const app = express();

// 创建路由
app.get('/home', (req, res) => {
    res.end('hello express');
});

app.listen(9000, () => {
    console.log('端口监听中...');
});

2.2、express路由

一个路由有三个部分组成,请求方法、路径和回调函数。

// 导入
const express = require('express');

// 创建应用对象
const app = express();

// 创建路由
app.get('/home', (req, res) => {
    res.end('hello express');
});

app.get('/', (req, res) => {
    res.end('home');
});

app.post('/login', (req, res) => {
    res.end('test');
});

app.all('/test', (req, res) => {
    res.end('all test');
});

// 404响应,上面没有一个匹配就走这个路由
app.all('*', (req, res) => {
    res.end('404');
});

app.listen(9000, () => {
    console.log('端口监听中...');
});

2.3、获取请求报文参数

// 导入
const express = require('express');

// 创建应用对象
const app = express();

// 创建路由
app.get('/request', (req, res) => {
    // 原生操作
    console.log(req.method);
    console.log(req.url);
    console.log(req.httpVersion);
    console.log(req.headers);

    // express操作
    console.log(req.path);
    console.log(req.query);
    // 获取ip
    console.log(req.ip);
    // 获取请求头
    console.log(req.get('host'));
});

app.listen(9000, () => {
    console.log('端口监听中...');
});

2.4、获取路由参数

// 导入
const express = require('express');

// 创建应用对象
const app = express();

// 创建路由
app.get('/:id.html', (req, res) => {
    // 获取URL路由参数
    console.log(req.params.id);
});

app.listen(9000, () => {
    console.log('端口监听中...');
});

2.5、响应设置

express封装了一些API方便给客户端响应数据,并且兼容原生HTTP模块的获取方式。

// 导入
const express = require('express');

// 创建应用对象
const app = express();

// 创建路由
app.get('/response', (req, res) => {
    // 1、express中设置响应的方式兼容HTTP模块的方式
    res.statusCode = 404;
    res.statusMessage = 'xxx';
    res.setHeader('abc','xyz');
    res.write('响应体');
    res.end('xxx');

    // 2、express的响应方法
    res.status(500);
    res.set('xxx', 'yyy'); // 设置响应头
    res.send('xxx'); // 设置响应体
    // 连贯操作
    res.status(404).set().send()

    // 3、其他响应
    res.redirect('http://www.baidu.com'); // 重定向
    res.download('./package.json'); // 下载响应
    res.json(); // 响应JSON
    res.sendFile(__dirname + '/home.html'); // 响应文件内容
});

app.listen(9000, () => {
    console.log('端口监听中...');
});

2.6、express中获取请求体的数据

express可以使用body-parser包处理请求体。

安装:npm i body-parser

使用:

// 导入
const express = require('express');
const bodyParser = require('body-parser');

// 创建应用对象
const app = express();

// 解析JSON格式的请求体的中间件
const jsonParser = bodyParser.json();

// 解析querystring格式请求体的中间件
const urlencodedParser = bodyParser.urlencoded({ extended: false});

// 创建路由规则
app.get('/login', (req, res) => {
    // res.send('表单页面');
    res.sendFile(__dirname + '/index.html');
});

app.post('/login', urlencodedParser, (req, res) => {
    console.log(req.body);
    res.send('获取用户数据');
});

app.listen(9000, () => {
    console.log('端口监听中...');
});

3、中间件

3.1、什么是中间件

Middleware本质上是一个回调函数。可以像路由一样访问请求对象和响应对象。

作用:用于封装公共操作,简化代码。

3.2、类型

  • 全局中间件
  • 路由中间件

3.3、全局中间件

每一个请求到达服务端之后,都会执行全局中间件函数。

// 导入
const express = require('express');
const fs = require('fs');
const path = require('path');

// 创建应用对象
const app = express();

// 声明中间件函数
function recordMiddleware(req, res, next) {
    // 获取 url 和 ip
    let { url, ip } = req;
    // 将信息保存在文件中 access.log
    fs.appendFileSync(path.resolve(__dirname, './access.log'), `${url}   ${ip}\r\n`);
    next();
}

// 使用中间件函数
app.use(recordMiddleware);

// 创建路由
app.get('/home', (req, res) => {
    res.send('前台首页'); 
});

app.get('/admin', (req, res) => {
    res.send('后台首页'); 
});

app.all('*', (req, res) => {
    res.send('404 no found');
});

app.listen(9000, () => {
    console.log('端口监听中...');
});

3.4、路由中间件

// 导入
const express = require('express');

// 创建应用对象
const app = express();

// 创建路由
app.get('/home', (req, res) => {
    res.send('前台首页'); 
});

// 声明中间件
let checkCodeMiddlerware = (req, res, next) => {
    if (req.query.code === '521') {
       next();
    } else {
        res.send('暗号错误');
    }
}

app.get('/admin', checkCodeMiddlerware, (req, res) => {
    res.send('后台首页'); 
});

app.get('/setting', checkCodeMiddlerware, (req, res) => {
    res.send('设置页面'); 
});

app.all('*', (req, res) => {
    res.send('404 no found');
});

app.listen(9000, () => {
    console.log('端口监听中...');
});

3.5、静态资源中间件

express内置处理静态资源的中间件。

// 导入
const express = require('express');

// 创建应用对象
const app = express();

// 静态资源中间件设置
app.use(express.static(__dirname + '/public'));

// 创建路由
app.get('/home', (req, res) => {
    res.send('前台首页'); 
});

app.all('*', (req, res) => {
    res.send('404 no found');
});

app.listen(9000, () => {
    console.log('端口监听中...');
});

注意事项:

  • 1、index.html为文件默认打开的资源。
  • 2、如果静态资源与路由规则同时匹配,谁先匹配谁就响应。
  • 3、路由响应动态资源,静态资源中间件响应静态资源。

4、防盗链

通过请求头中的referer来判断。

// 导入
const express = require('express');
const bodyParser = require('body-parser');

// 创建应用对象
const app = express();

// 声明中间件,防盗链
app.use((req, res, next) => {
    // 检测请求头中的referer是否是127.0.0.1
    let referer = req.get('referer');
    console.log(referer);
    if (referer) {
        let url = new URL(referer);
        let hostname = url.hostname;
        if (hostname !== '127.0.0.1') {
            res.status(404).send('not found');
        }
    }
    next();
})

app.listen(9000, () => {
    console.log('端口监听中...');
});

5、路由模块化

创建routes文件夹,用来统一存放路由文件。

routes/homeRouter.js

// 导入
const express = require('express');

// 创建路由对象
const router = express.Router();

router.get('/home', (req, res) => {
    res.send('后台首页');
});

module.exports = router;

6、模板引擎EJS

分离用户界面和业务数据的一种技术。

EJS是一种高效的JS的模板引擎。

安装:npm i ejs --save

6.1、初体验

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>我爱你 <%= china %></h1>
    <%= weather %>
</body>
</html>

index.js

const ejs = require('ejs');
const fs = require('fs');

let china = '中国';
let weather = '天气晴';

let str = fs.readFileSync('./index.html').toString();
let result = ejs.render(str, {china, weather});
console.log(result);

6.2、ejs列表渲染

const ejs = require('ejs');
const fs = require('fs');

let arr = [1,2,3,4,5];

let result = ejs.render(`<ul>
    <% arr.forEach(item => { %>
        <li><%= item %></li>
    <% }) %>
</ul>
`, { arr });

console.log(result);

6.3、ejs的条件渲染

const ejs = require('ejs');
const fs = require('fs');

let isTrue = false;

let result = ejs.render(`
    <% if (isTrue) { %>
        <span>主人</span>
    <% } else { %>
        其他人
    <% } %>
`, { isTrue });

console.log(result);

6.4、express中使用EJS

创建views文件夹,用于存放模板文件,后缀名是ejs。

views/home.ejs:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1><%= title %></h1>
</body>
</html>

index.js:

// 导入
const express = require('express');
const path = require('path');

// 创建应用对象
const app = express();
// 1、设置模板引擎
app.set('view engine', 'ejs'); 
// 2、设置模板引擎文件存放位置
app.set('views', path.resolve(__dirname, './views'));

// 创建路由
app.get('/home', (req, res) => {
    let title = '你好';
    res.render('home', {title});
});

app.all('*', (req, res) => {
    res.send('<h1>404 not found!</h1>');
});

app.listen(9000, () => {
    console.log('端口监听中...');
});

7、express-generator工具

通过应用生成工具express-generator可以快速创建一个应用的骨架,相当于脚手架

可以通过npx(包含在Node.j
s8.2.0以及更高版本中)命令来运行Express应用程序生成器。

npx express-generator

对于较老版本的node,请通过npm将Express应用程序生成器安装到全局环境中使用:

npm install -g express-generator

express -e <项目名>,创建项目。

npm i 安装项目的依赖。

-h参数可以列出所有可用的命令行参数。

8、文件上传

使用formidable处理文件上传的请求。

npm i formidable

var express = require('express');
var router = express.Router();
// 导入
const path = require('path');
const formidable = require('formidable');

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

// 显示网页的表单
router.get('/portrait', (req, res) => {
  res.render('portrait');
});

// 处理文件上传
router.post('/portrait', (req, res) => {
  const form = formidable({ 
    multiples: true,
    // 设置文件的保存目录
    uploadDir: path.resolve(__dirname, '../public/images'),
    // 保持文件后缀
    keepExtensions: true,
  });
  // 解析请求报文
  form.parse(req, (err, fields, files) => {
    if (err) {
      // next(err);
      console.log(err);
      return;
    }
    console.log(fields); // text rdion checkbox select
    console.log(files); // file
    // 服务器保存该图片的访问URL
    let url  = '/images/' + files.portrait.newFilename; // 将来将此数据保存在数据库中
    res.send(url);
  });
});

module.exports = router;

posted @ 2023-05-18 19:08  笔下洛璃  阅读(92)  评论(0编辑  收藏  举报