前言

常见的nodejs框架有:

  1. express: Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。
  2. koa: 现在一般都用koa2, 是express原班人马打造的, 对比于Express框架,丢弃了回调函数,并有效地增强了异常处理

丢弃回调函数是因为Koa使用Promise配合Async函数实现异步,解决了Node回调地狱的问题。

  1. egg.js 阿里出品
  2. hapi.js 沃尔玛
  3. nestJS: NestJS是基于NodeJS的快速开发框架,内含各种快速开发工具 包含但不限于JWT、TypeORM等

    (一) hello word

  4. 初始化package.json
    新建目录koademo,执行 npm init,一路回车

  5. 创建一个简单的koa应用(hello world)
    安装koa模块 npm install koa —save
    在项目根目录新建app.js,app.js代码如下:
  1. var Koa = require('koa');
  2. var app = new Koa();
  3. app.use(function(ctx) {
  4. ctx.body = 'hello worlod2222';
  5. })
  6. app.listen(8888, function() {
  7. console.log('服务已启动, 在http://localhost:8888')
  8. })
  1. 执行node app.js
  2. 用浏览器访问 http://localhost:3000

Ps: 端口被占用, 解决办法

  1. netstat -aon|findstr 3000 查看谁在使用3000端口, 最后一个值为pid
  2. kill pid

(二) koa路由 koa-router

  1. 创建新文件夹koa-router-app作为项目的根目录
  2. 打开终端执行以下命令

    1. npm init -y // 初始化package.json
    2. npm i koa-router --save-dev // 安装koa和koa-router
  3. 新建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/‘); });

  1. 4. 打开终端启动服务,用浏览器访接口即可

nodemon app.js

  1. <a name="2d6ecca9"></a>
  2. ## (三) 封装路由
  3. 介绍: 项目中, 因为接口比较多, 所以一边会把路由放在另外一个文件里, 做成一个模块
  4. 1. 创建新文件夹koa-router-app2作为项目的根目录
  5. 1. 打开终端执行以下命令
  6. ```javascript
  7. npm init -y // 初始化package.json
  8. npm i koa koa-router --save-dev // 安装koa和koa-router
  1. 新建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/‘); });

  1. 4. 新建router.js, 代码如下
  2. ```javascript
  3. // 1.导入koa-router
  4. var Router = require('koa-router');
  5. // 2.创建一个router对象
  6. var router = new Router();
  7. // 3.创建路由
  8. router.get('/', function(ctx) {
  9. ctx.body = 'hello world'
  10. })
  11. router.get('/demo1', function(ctx) {
  12. ctx.body = 'aaaaaaaaa';
  13. })
  14. router.post('/demo2', function(ctx) {
  15. ctx.body = 'bbbbb'
  16. })
  17. router.all('/demo3', function(ctx) {
  18. ctx.body = 'ccccccc'
  19. });
  20. // 导出路由对象
  21. module.exports = router;
  1. 浏览器访问http://localhost:3000/city/add (或其他) 即可

(三) koa中间件

一个请求从发出到返回数据,如果我们想在这个过程里做一些统一的操作,可以使用中间件来完成.

  1. 中间件是个函数
  2. 使用中间件的方式, 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/‘); });

  1. 3. 获取中间件存入的信息
  2. ```typescript
  3. // 1.导入koa-router
  4. var Router = require('koa-router');
  5. // 2.创建一个router对象
  6. var router = new Router();
  7. router.get('/demo1', function(ctx) {
  8. ctx.body = {
  9. username: ctx.username,
  10. age: ctx.age,
  11. data: 'asdfasdfas'
  12. };
  13. })
  14. module.exports = router;
  1. 中间件是有先后顺序 ```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(); })

  1. <a name="fa6f85e1"></a>
  2. ## (四) 设置静态目录
  3. 1. 在目录中创建目录public,在public下创建文件demo.html,访问http://localhost:3000/public/demo.html是无法访问得到,因为我们还没有设置静态资源目录,设置静态资源目录要用到koa-static模块
  4. 1. 安装koa-static

npm i koa-static —save-dev

  1. 3. app.j是里加入如下代码

var koaStatic = require(‘koa-static’); app.use(koaStatic(__dirname + ‘/public’));

  1. 再来访问 [http://localhost:3000/demo.html](http://localhost:3000/demo.html) 就可以访问了,ps: 路径不用加public
  2. <a name="4b090ddc"></a>
  3. ## (五) 获取请求参数
  4. 1. 给刚才的demo.html添加axios用来发送请求,代码如下:
  5. ```typescript
  6. <!DOCTYPE html>
  7. <html lang="en">
  8. <head>
  9. <meta charset="UTF-8">
  10. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  11. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  12. <title>Document</title>
  13. <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
  14. </head>
  15. <body>
  16. <h3>get请求和post请求</h3>
  17. <button onclick="get();">发送get请求</button>
  18. <button onclick="post();">发送post请求</button>
  19. <script>
  20. function get() {
  21. $.ajax({
  22. type: 'get',
  23. url: 'http://localhost:3000/demo1',
  24. data: {
  25. aa: '1111',
  26. bb: '2222'
  27. },
  28. dataType: 'json',
  29. success: function(res) {
  30. console.log(res);
  31. },
  32. error: function(err) {
  33. console.log(err);
  34. }
  35. })
  36. }
  37. function post() {
  38. $.ajax({
  39. type: 'post',
  40. url: 'http://localhost:3000/demo2',
  41. data: {
  42. aa: '1111',
  43. bb: '2222'
  44. },
  45. dataType: 'json',
  46. success: function(res) {
  47. console.log(res);
  48. },
  49. error: function(err) {
  50. console.log(err);
  51. }
  52. })
  53. }
  54. </script>
  55. </body>
  56. </html>
  1. 获取get请求参数

在router.js的add接口里加入如下代码

  1. router.all('/add', function(ctx) {
  2. // // get请求,请求参数放在ctx.query对象里
  3. const username = ctx.query.username;
  4. const phone = ctx.query.phone;
  5. // 把拿到的数据放入ctx.body
  6. ctx.body = {
  7. module: 'add',
  8. username,
  9. phone
  10. }
  11. })
  1. 获取post请求
  1. // 1.设置
  2. npm i koa-body --save // 安装koa-body模块
  1. // 2.在app.js里加上以下代码:
  2. var koaBody = require('koa-body');
  3. app.use(koaBody());
  1. // 2.获取请求参数,前端的请求参数存在ctx.request.body对象里
  2. ctx.request.body.xxx
  1. // 处理请求参数的中间件, 把get和post的请求参数都放入ctx.params对象, 方便获取请求参数
  2. app.use(function(ctx, next) {
  3. var query = ctx.query;
  4. var body = ctx.request.body;
  5. var params = {};
  6. for (var p in query) {
  7. params[p] = query[p];
  8. }
  9. for (var p in body) {
  10. params[p] = body[p];
  11. }
  12. ctx.params = params;
  13. next();
  14. });
  1. // 获取请求参数就可以这么写
  2. router.all('/demo3', function(ctx) {
  3. // 打印请求参数ctx.prams
  4. console.log(ctx.params);
  5. ctx.body = 'ccccccc'
  6. });

(六) 使用模板(了解)

一般请求一个接口返回的是一坨数据,然而有时候我们希望返回的是一个html网页或者一段html代码(上周分享的服务器渲染)
我们试用koa-swig模块来向前端返回一个html

  1. 安装underscore 和 koa-swig
  1. npm i underscore koa-view --save-dev

在根目录创建views目录,在views目录下创建tpl.html,代码如下

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  7. <title>Document</title>
  8. </head>
  9. <body>
  10. <h3>
  11. <%=title %>
  12. </h3>
  13. </body>
  14. </html>
  1. 在app.js添加如下代码:
  1. var Koa = require('koa');
  2. var path = require('path');
  3. var app = new Koa();
  4. var views = require("koa-views");
  5. app.use(views(path.join(__dirname, "views"), {
  6. map: {
  7. html: 'underscore'
  8. }
  9. }));
  10. app.use(async function(ctx) {
  11. await ctx.render('tpl', {
  12. title: '啊啊啊啊啊啊',
  13. });
  14. })
  15. app.listen(3000, function() {
  16. console.log('server running at http://localhost:3000')
  17. })
  1. 访问 http://localhost:3000,就可以看到一个html页面

(七) 跨域配置

自己编写一个中间件即可,代码如下

  1. app.use(async function(ctx, next) {
  2. ctx.set("Access-Control-Allow-Origin", "*");
  3. ctx.set("Access-Control-Allow-Methods", "PUT, POST, GET, DELETE, OPTIONS");
  4. // 请求头设置
  5. ctx.set(
  6. "Access-Control-Allow-Headers",
  7. `Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild,x-token,sessionToken,token`
  8. );
  9. if (ctx.method == "OPTIONS") {
  10. ctx.body = 200;
  11. } else {
  12. await next();
  13. }
  14. })

访问刚才的demo.html文件, http://localhost:3000/demo.html,你会发现你的请求的响应头上添加了Access-Control-Allow-Origin: *,说明服务器跨域设置已经成功了.

(八) 模拟数据(重要)

(1) 为什么要模拟数据

(2) 模拟数据的流程

  1. 先让后端的同事把接口名称, 返回数据的格式(字段名称)定义好
  2. 前端的同事根据接口名称,字段来进行模拟数据
  3. 等后端把接口开发好之后, 前端和后端进行联调接口

    (3) 模拟数据的几种方式

  4. 使用json文件进行模拟数据, 需要用工具启动一个服务,比如 serve

    1. (1)npm i serve -g // 全局安装serve模块
    2. (2)进行项目文件夹, 运行命了 serve
  5. 使用nodejs创建服务模拟数据

    (4) 互联网上的一些工具

(九) 图片上传

  1. var Router = require('koa-router')
  2. var router = new Router();
  3. var fs = require('fs');
  4. var path = require('path');
  5. router.all("/upload", async ctx=> {
  6. try {
  7. const file = ctx.request.files.file;
  8. let fileName = file.name;
  9. // 创建可读流
  10. const render = fs.createReadStream(file.path);
  11. // 指定存放路径
  12. let filePath = path.join(__dirname, './public/',fileName);
  13. const upStream = fs.createWriteStream(filePath);
  14. render.pipe(upStream);
  15. // 给前端返回图片地址,xxx.xxx.xxx:xxxx是你的服务器地址和端口号
  16. let imgUrl = 'http://xxx.xxx.xxx:xxxx/'+'/upload/'+fileName;
  17. ctx.body = {
  18. code: 666,
  19. msg: '上传成功',
  20. result: {
  21. imgUrl
  22. }
  23. }
  24. } catch (error) {
  25. console.log(error);
  26. ctx.body = {
  27. code: 500,
  28. msg: '上传失败'
  29. }
  30. }
  31. })
  1. <body>
  2. <div>
  3. <form>
  4. <input type="text" class="filename">
  5. <input type="file" name="file" class="imgPath">
  6. <div class="submitBtn">提交</div>
  7. </form>
  8. </div>
  9. <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
  10. <script type="text/javascript">
  11. $(document).ready(function(){
  12. $('.submitBtn').on('click',() => {
  13. var params = new FormData();
  14. params.append('name',$('.filename').val())
  15. params.append('file',$('.imgPath')[0].files[0])
  16. $.ajax({
  17. data: params,
  18. url: 'http://localhost:3000/upload',
  19. type: 'post',
  20. processData: false,
  21. contentType: false,
  22. success: function(res) {
  23. console.log(res)
  24. }
  25. })
  26. })
  27. })
  28. </script>
  29. </body>