手把手教你搭建一个【文件共享平台】系列教程第三话——Koa初步使用(路由、静态文件、session、跨域)

本话概要

【绝对干货】🔥
本篇博文主要介绍文件共享平台的后端如何搭建。从几个方面入手:路由怎么配置?静态文件路径如何设置?session的用途及配置?跨域问题如何解决?
通过本文,你可以基本了解整个后端的搭建流程及关键步骤。我建议你和我一步步操作,真正实现后端架构搭建。
当然,本文仅仅是后端教程的开端,其他教程将在后续更新。👇

Koa介绍

Koa 是一个新的 web 框架,由 Express 幕后的原班人马打造, 致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石。 通过利用 async 函数,Koa 帮你丢弃回调函数,并有力地增强错误处理。 Koa 并没有捆绑任何中间件, 而是提供了一套优雅的方法,帮助您快速而愉快地编写服务端应用程序。官网
在这里插入图片描述
你可以把koa看作express的替代品,koa的一些语法糖使得后端搭建更加简单,且丰富的node库资源,很多功能的中间件都已被封装好,例如koa-static、koa2-cors、koa-body等。下面我们就进入实战,教大家如何搭建后端。

从一个app.js开始

首先,创建一个项目文件夹,命名为shareFile_server。
在该文件夹下初始化node项目

npm init

然后我们就得到一个基本的node项目结构。
接下来,我们创建一个app.js文件,作为服务器的运行代码。

安装包

首先将需要的node包一次性安装好,安装方法如下:

npm install koa koa-body koa-router koa-session koa-static koa2-cors --save-dev

如果你觉得一次性都下载,有中途报错的风险,你也可以一个一个安装。如果觉得下载太慢,也可以用淘宝镜像安装方法,安装方法如下:

npm --registry https://registry.npm.taobao.org install 包名 --save-dev

所有包安装好后,我们进入coding环节。

允许多文件上传

文件共享平台自然需要服务端允许文件上传,这里设置多文件上传。配置很简单,引入koa-body。

// app.js
app.use(koaBody({
  multipart: true, // 支持多文件上传
  formidable: {
    maxFieldsSize: 5 * 1024 * 1024, // 最大文件为5兆
    multipart: true // 是否支持 multipart-formdate 的表单
  }
})
);

配置路由

首先,服务端需要解决路由问题。简单来说,路由就是根据不同的访问路径,返回不同的资源文件或者不同的结果字段。比如,你访问一个静态资源(图片、文件),服务器应该返回静态资源本身;如果你想查询数据库,服务器应该返回查询后的结果,以json的形式返回给浏览器。这就是路由的作用。路由使得服务端的功能很容易得到扩展,而不是单一的功能。
利用koa配置路由写法非常优美。首先我们在app.js头部引入koa包并创建示例:

const Koa = require('koa');
const app = new Koa();

为了使得路由功能更加集中,我将路由部分提到单独的文件中。首先在根目录创建一个router的文件夹,然后在文件夹内创建一个index.js,作为路由的配置文件。
然后,在router文件夹下继续创建几个不同的路由模块:user.js、file.js、directory.js…这个依照不同的功能可以设置不同的路由。每一个路由模块对应了一个根路径。
接下来,在index.js中配置路由,写法如下:

// router/index.js
const router = require('koa-router')();
const directory = require('./directory');//处理文件夹
const file = require('./file');//处理文件
const user = require('./user');//处理用户

router.use('/directory',directory.routes(),directory.allowedMethods());
router.use('/file',file.routes(),file.allowedMethods());
router.use('/user',user.routes(),user.allowedMethods());

module.exports = router;

此时,你的项目文件夹结构应该是:

  • shareFile_server/
    • node_modules/
    • router/
      • index.js
      • file.js
      • user.js
      • directory.js
    • app.js
    • package.json
    • package-lock.json

接下来我们回到app.js文件中,引用该路由配置。

const router = require('./router/index');

// 加载路由中间件
app.use(router.routes(), router.allowedMethods());

另外,我们先把file.js、user.js和directory.js中写如下代码,保证程序可以正常运行:

// file.js、user.js、directory.js
const router = require('koa-router')();
//...待补充
module.exports = router;

这样,整体的路由配置流程我们就过了一遍。具体的路由怎么写,我将在后面的教程详述。不急~

设置静态文件路径

设置静态文件路径的原因,是我们这个文件共享平台本身的属性决定的。因为有一些文件是需要通过访问地址可以直接访问到的,例如图片,所以服务端需要把这些文件直接返回给浏览器,而如果用传统的办法,我们需要队每个请求都做一个判断,根据不同的文件类型,设置不同的content-type,以便浏览器识别出返回的文件类型,进行不同的响应。
另外,如果前端的代码也打包放到后台,我们就更需要设置静态文件路径了,否则就会出现404(Not Found)的问题。当然,本系列教程的前后端代码并没有统一放在后端,后端的静态文件单纯指文件存储的文件夹。
现在通过koa-static包,我们可以直接配置静态文件的路径,省去很多烦恼。
首先,我们在根目录创建一个static文件夹,作为静态资源文件目录。
然后,我们在app.js中写如下代码:

const serve = require('koa-static');
app.use(serve(path.join(__dirname,'static')));

这样,我们就设置好了静态文件路径。需要注意的是,设置了静态文件路径后,通过浏览器访问该资源,不要出现static这个路径,而是直接访问static内的文件,因为默认是以static作为根目录的。比如,端口是8000,我们要访问static/img/example.png,需要按照如下链接访问:

http://localhost:8000/img/example.png

设置session

首先解释下为什么需要设置session。
session是浏览器访问服务器,会在服务器端的内存里开辟一块内存,每个session都有属于自己的sessionid,用来区分不同客户。
准确来说,这个平台用session具体是要解决:用户是否在线的问题
如果用户未登录,需要跳转到登录页,如果已登录,就可以正常得到服务。
如何判断用户是否在线,常用的解决方案有两套:token和session鉴权。

token的原理是用户第一次访问服务器,服务器根据用户的唯一标识(如userid),用一些加密算法(如HMAC-SHA256),通过一个密匙,生成一个令牌(token),然后用Base64编码后发送给用户。用户将这个token保存起来,以后每次请求都带上这个token,服务端收到后用密匙验证token,来判断用户是否已登录。

Session鉴权的原理如图所示(忘记在哪里截图的了,不是自己画的)。用户登录后,服务器会向用户发放session ID,存在用户浏览器的cookie中,这个cookie用户在前端是无法修改的,当用户发送请求,请求头需要带上session ID这个cookie。服务器维护一个session表,通过设置一定的时长,来管理每个用户的登录状态,超时会将该用户的session删除,这样当用户从前端发来请求,后端的session表中不存在该session ID,就会提示用户重新登录。
在这里插入图片描述
为了实现session,我们在app.js中引用koa-session包:

const session = require('koa-session');

app.keys = ['never mind, just test'];

//设置session
app.use(session({
  key: 'koa:sess', /** cookie的名称,可以不管 */
  maxAge: 7200000, /** cookie的过期时间(毫秒),这里表示2个小时(2*60*60*1000) */
  overwrite: true, /** (boolean) can overwrite or not (default true) */
  httpOnly: true, /** (boolean) httpOnly or not (default true) */
  signed: true, /** (boolean) signed or not (default true) 是否加密,如果加密,需要给上面的app.keys赋值*/
  rolling: false, /** (boolean) Force a session identifier cookie to be set on every response. The expiration is reset to the original maxAge, resetting the expiration countdown. (default is false) */
  renew: false, /** (boolean) renew session when session is nearly expired, so we can always keep user logged in. (default is false)*/
},app));

这样就完成了session的配置,我们在后续登录鉴权的教程具体教大家怎么用session,很简单。

解决跨域问题

跨域问题是前后端交互经常遇到的问题。后端要解决跨域问题,需要进行配置,这里用koa2-cors解决跨域问题:

// app.js
const cors = require('koa2-cors');

//设置跨域参数
app.use(cors({
  origin: function(ctx) { //设置允许来自指定域名请求
    const whiteList = []; //可跨域白名单,这里设置前端的
    let url = ctx.header.origin;
    if(whiteList.includes(url)){
      return url
    }
    return 'http://localhost:3000' //默认允许本地请求3000端口可跨域
  },
  exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'],
  maxAge: 5,
  credentials: true,
  allowMethods: ['GET', 'POST', 'DELETE','PUT'],
  allowHeaders: ['Content-Type', 'Authorization', 'Accept'],
})
)

按照上述代码,我们解决了跨域问题。
最后我们需要把服务运行起来,设置服务端口为3000

app.listen(3000, () => {
  console.log('server is listen in 3000');
});

完整代码

// app.js完整代码

const Koa = require('koa');
const path = require('path');
const router = require('./router/index');
const koaBody = require('koa-body');
const serve = require('koa-static');
const cors = require('koa2-cors');
const session = require('koa-session');

const app = new Koa();

// 设置session
app.keys = ['never mind, just test'];

//设置session
app.use(session({
  key: 'koa:sess', 
  maxAge: 7200000, 
  overwrite: true, 
  httpOnly: true, 
  signed: true, 
  rolling: false,
  renew: false, 
},app));

//设置跨域参数
app.use(cors({
  origin: function(ctx) { //设置允许来自指定域名请求
    const whiteList = []; //可跨域白名单
    // let url = ctx.header.referer.substr(0,ctx.header.referer.length - 1); 
    let url = ctx.header.origin;
    if(whiteList.includes(url)){
      return url 
    }
    return 'http://localhost:3000' //默认允许本地请求3000端口可跨域
  },
  exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'],
  maxAge: 5,
  credentials: true,
  allowMethods: ['GET', 'POST', 'DELETE','PUT'],
  allowHeaders: ['Content-Type', 'Authorization', 'Accept'],
})
)

//多文件上传
app.use(koaBody({
  multipart: true, 
  formidable: {
    maxFieldsSize: 5 * 1024 * 1024, // 最大文件为5兆
    multipart: true 
  }
})
);

// 设置静态文件路径
app.use(serve(path.join(__dirname,'static')));

// 加载路由中间件
app.use(router.routes(), router.allowedMethods());

app.listen(3000, () => {
  console.log('server is listen in 3000');
});

我们运行app.js

node app.js

如果没有报错,说明基本架构没问题~大功告成👌你学会了吗?

下期预告

下一话,我将教大家后台如何与mongodb交互,并封装CURD操作,提高通用性。怀挺💪
下期再见👋

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HouGISer

HouGiser需要你的鼓励~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值