前言
常见的nodejs框架有:
- express: Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。
- koa: 现在一般都用koa2, 是express原班人马打造的, 对比于Express框架,丢弃了回调函数,并有效地增强了异常处理。
丢弃回调函数是因为Koa使用Promise配合Async函数实现异步,解决了Node回调地狱的问题。
- egg.js 阿里出品
- hapi.js 沃尔玛
nestJS: NestJS是基于NodeJS的快速开发框架,内含各种快速开发工具 包含但不限于JWT、TypeORM等
(一) hello word
初始化package.json
新建目录koademo,执行 npm init,一路回车- 创建一个简单的koa应用(hello world)
安装koa模块 npm install koa —save
在项目根目录新建app.js,app.js代码如下:
var Koa = require('koa');
var app = new Koa();
app.use(function(ctx) {
ctx.body = 'hello worlod2222';
})
app.listen(8888, function() {
console.log('服务已启动, 在http://localhost:8888')
})
- 执行node app.js
- 用浏览器访问 http://localhost:3000
Ps: 端口被占用, 解决办法
netstat -aon|findstr 3000 查看谁在使用3000端口, 最后一个值为pid
kill pid
(二) koa路由 koa-router
- 创建新文件夹koa-router-app作为项目的根目录
打开终端执行以下命令
npm init -y // 初始化package.json
npm i koa-router --save-dev // 安装koa和koa-router
新建app.js,代码如下 ```typescript var Koa = require(‘koa’); // 1.导入koa-router var Router = require(‘koa-router’); var app = new Koa(); // 2.创建一个router对象 var router = new Router();
// 3.创建路由 router.get(‘/‘, function(ctx) { ctx.body = ‘hello world’ }) router.get(‘/demo1’, function(ctx) { ctx.body = ‘aaaaaaaaa’; }) router.post(‘/demo2’, function(ctx) { ctx.body = ‘bbbbb’ }) router.all(‘/demo3’, function(ctx) { ctx.body = ‘ccccccc’ }); // 4.使路由生效 app.use(router.routes());
app.listen(3000, () => { console.log(‘服务已启动,在 http://localhost:3000/‘); });
4. 打开终端启动服务,用浏览器访接口即可
nodemon app.js
<a name="2d6ecca9"></a>
## (三) 封装路由
介绍: 项目中, 因为接口比较多, 所以一边会把路由放在另外一个文件里, 做成一个模块
1. 创建新文件夹koa-router-app2作为项目的根目录
1. 打开终端执行以下命令
```javascript
npm init -y // 初始化package.json
npm i koa koa-router --save-dev // 安装koa和koa-router
- 新建app.js,代码如下 ```javascript var Koa = require(‘koa’) var app = new Koa() var router = require(‘./router’);
app.use(router.routes());
app.listen(3000, () => { console.log(‘服务已启动,在 http://localhost:3000/‘); });
4. 新建router.js, 代码如下
```javascript
// 1.导入koa-router
var Router = require('koa-router');
// 2.创建一个router对象
var router = new Router();
// 3.创建路由
router.get('/', function(ctx) {
ctx.body = 'hello world'
})
router.get('/demo1', function(ctx) {
ctx.body = 'aaaaaaaaa';
})
router.post('/demo2', function(ctx) {
ctx.body = 'bbbbb'
})
router.all('/demo3', function(ctx) {
ctx.body = 'ccccccc'
});
// 导出路由对象
module.exports = router;
- 浏览器访问http://localhost:3000/city/add (或其他) 即可
(三) koa中间件
一个请求从发出到返回数据,如果我们想在这个过程里做一些统一的操作,可以使用中间件来完成.
- 中间件是个函数
- 使用中间件的方式, app.use(中间件) ```typescript var Koa = require(‘koa’); var app = new Koa(); var router = require(‘./router’);
// 添加中间件 app.use(function(ctx, next) { ctx.username = ‘老胡’; // 调用next,执行下个中间件,直到返回数据 next(); }) app.use(function(ctx, next) { ctx.age = 100; next(); })
// 4.使路由生效 app.use(router.routes());
app.listen(3000, () => { console.log(‘服务已启动,在 http://localhost:3000/‘); });
3. 获取中间件存入的信息
```typescript
// 1.导入koa-router
var Router = require('koa-router');
// 2.创建一个router对象
var router = new Router();
router.get('/demo1', function(ctx) {
ctx.body = {
username: ctx.username,
age: ctx.age,
data: 'asdfasdfas'
};
})
module.exports = router;
- 中间件是有先后顺序 ```typescript app.use(function(ctx, next) { ctx.username = ‘laohu’; console.log(ctx.age); // undefined next(); })
app.use(function(ctx, next) { ctx.age = 100; console.log(ctx.username); // laohu next(); })
<a name="fa6f85e1"></a>
## (四) 设置静态目录
1. 在目录中创建目录public,在public下创建文件demo.html,访问http://localhost:3000/public/demo.html是无法访问得到,因为我们还没有设置静态资源目录,设置静态资源目录要用到koa-static模块
1. 安装koa-static
npm i koa-static —save-dev
3. 在app.j是里加入如下代码
var koaStatic = require(‘koa-static’); app.use(koaStatic(__dirname + ‘/public’));
再来访问 [http://localhost:3000/demo.html](http://localhost:3000/demo.html) 就可以访问了,ps: 路径不用加public
<a name="4b090ddc"></a>
## (五) 获取请求参数
1. 给刚才的demo.html添加axios用来发送请求,代码如下:
```typescript
<!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>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<h3>get请求和post请求</h3>
<button onclick="get();">发送get请求</button>
<button onclick="post();">发送post请求</button>
<script>
function get() {
$.ajax({
type: 'get',
url: 'http://localhost:3000/demo1',
data: {
aa: '1111',
bb: '2222'
},
dataType: 'json',
success: function(res) {
console.log(res);
},
error: function(err) {
console.log(err);
}
})
}
function post() {
$.ajax({
type: 'post',
url: 'http://localhost:3000/demo2',
data: {
aa: '1111',
bb: '2222'
},
dataType: 'json',
success: function(res) {
console.log(res);
},
error: function(err) {
console.log(err);
}
})
}
</script>
</body>
</html>
- 获取get请求参数
在router.js的add接口里加入如下代码
router.all('/add', function(ctx) {
// // get请求,请求参数放在ctx.query对象里
const username = ctx.query.username;
const phone = ctx.query.phone;
// 把拿到的数据放入ctx.body
ctx.body = {
module: 'add',
username,
phone
}
})
- 获取post请求
// 1.设置
npm i koa-body --save // 安装koa-body模块
// 2.在app.js里加上以下代码:
var koaBody = require('koa-body');
app.use(koaBody());
// 2.获取请求参数,前端的请求参数存在ctx.request.body对象里
ctx.request.body.xxx
// 处理请求参数的中间件, 把get和post的请求参数都放入ctx.params对象, 方便获取请求参数
app.use(function(ctx, next) {
var query = ctx.query;
var body = ctx.request.body;
var params = {};
for (var p in query) {
params[p] = query[p];
}
for (var p in body) {
params[p] = body[p];
}
ctx.params = params;
next();
});
// 获取请求参数就可以这么写
router.all('/demo3', function(ctx) {
// 打印请求参数ctx.prams
console.log(ctx.params);
ctx.body = 'ccccccc'
});
(六) 使用模板(了解)
一般请求一个接口返回的是一坨数据,然而有时候我们希望返回的是一个html网页或者一段html代码(上周分享的服务器渲染)
我们试用koa-swig模块来向前端返回一个html
- 安装underscore 和 koa-swig
npm i underscore koa-view --save-dev
在根目录创建views目录,在views目录下创建tpl.html,代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h3>
<%=title %>
</h3>
</body>
</html>
- 在app.js添加如下代码:
var Koa = require('koa');
var path = require('path');
var app = new Koa();
var views = require("koa-views");
app.use(views(path.join(__dirname, "views"), {
map: {
html: 'underscore'
}
}));
app.use(async function(ctx) {
await ctx.render('tpl', {
title: '啊啊啊啊啊啊',
});
})
app.listen(3000, function() {
console.log('server running at http://localhost:3000')
})
(七) 跨域配置
自己编写一个中间件即可,代码如下
app.use(async function(ctx, next) {
ctx.set("Access-Control-Allow-Origin", "*");
ctx.set("Access-Control-Allow-Methods", "PUT, POST, GET, DELETE, OPTIONS");
// 请求头设置
ctx.set(
"Access-Control-Allow-Headers",
`Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild,x-token,sessionToken,token`
);
if (ctx.method == "OPTIONS") {
ctx.body = 200;
} else {
await next();
}
})
访问刚才的demo.html文件, http://localhost:3000/demo.html,你会发现你的请求的响应头上添加了Access-Control-Allow-Origin: *,说明服务器跨域设置已经成功了.
(八) 模拟数据(重要)
(1) 为什么要模拟数据
(2) 模拟数据的流程
- 先让后端的同事把接口名称, 返回数据的格式(字段名称)定义好
- 前端的同事根据接口名称,字段来进行模拟数据
-
(3) 模拟数据的几种方式
使用json文件进行模拟数据, 需要用工具启动一个服务,比如 serve
(1)npm i serve -g // 全局安装serve模块
(2)进行项目文件夹, 运行命了 serve
-
(4) 互联网上的一些工具
(九) 图片上传
var Router = require('koa-router')
var router = new Router();
var fs = require('fs');
var path = require('path');
router.all("/upload", async ctx=> {
try {
const file = ctx.request.files.file;
let fileName = file.name;
// 创建可读流
const render = fs.createReadStream(file.path);
// 指定存放路径
let filePath = path.join(__dirname, './public/',fileName);
const upStream = fs.createWriteStream(filePath);
render.pipe(upStream);
// 给前端返回图片地址,xxx.xxx.xxx:xxxx是你的服务器地址和端口号
let imgUrl = 'http://xxx.xxx.xxx:xxxx/'+'/upload/'+fileName;
ctx.body = {
code: 666,
msg: '上传成功',
result: {
imgUrl
}
}
} catch (error) {
console.log(error);
ctx.body = {
code: 500,
msg: '上传失败'
}
}
})
<body>
<div>
<form>
<input type="text" class="filename">
<input type="file" name="file" class="imgPath">
<div class="submitBtn">提交</div>
</form>
</div>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('.submitBtn').on('click',() => {
var params = new FormData();
params.append('name',$('.filename').val())
params.append('file',$('.imgPath')[0].files[0])
$.ajax({
data: params,
url: 'http://localhost:3000/upload',
type: 'post',
processData: false,
contentType: false,
success: function(res) {
console.log(res)
}
})
})
})
</script>
</body>