前言
常见的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端口, 最后一个值为pidkill pid
(二) koa路由 koa-router
- 创建新文件夹koa-router-app作为项目的根目录
打开终端执行以下命令
npm init -y // 初始化package.jsonnpm 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. 打开终端执行以下命令```javascriptnpm init -y // 初始化package.jsonnpm 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-routervar 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-routervar 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.bodyctx.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.pramsconsole.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>
