# 路由

路由的概念来源于服务端,在服务端中路由描述的是URL与处理函数之间的对应关系。

路由是引导、匹配之意,于描述 URL 与处理函数之间的对应关系的。根据URL变更重新渲染页面布局和内容的过程。 传统路由整个界面切换,白屏等多个问题,体验不好。而前端路由则以SPA为准则,体验更佳:在页面不刷新的前提下实现URL变化且能捕捉到变化做出相应的逻辑。

const{url,path,method}=ctx ;
console.log(url===path)//true

put delete get post all等,all()一般用于设置请求头,如设置过期时间,CORS

 router.all('/*',async(ctx,next)=>{
	 ctx.set('Access-Control-Allow-Origin',''https://xxxx/xx)
 })

# 命名路由

使用router.url()方法可以在代码中根据路由名称和参数(可选)生成具体URL

//设置了路由名称为user
 router.get('user', '/users/:id', function (ctx, next) {
  // ... 
});

router.url('user', 3);
// => 生成路由 "/users/3" 

router.url('user', { id: 3 });
// => 生成路由 "/users/3" 

router.use(function (ctx, next) {
  // 重定向到路由名称为 “sign-in” 的页面 
  ctx.redirect(ctx.router.url('sign-in'));
})

# 多中间件

可把一个路由拆分,更佳容易维护

 const koa = require('koa')
 const compose=require('koa-compose')
 const bodyParser=require('koa-bodyparser')
 const Router=require('koa-router')
 const app = new koa() 
 const router= new Router()
 
 router.get('/100',(ctx,next)=>{
 	ctx.body='1000'
 	next()
 },(ctx,next)=>{
 	console.log(1000)
 })

 app
 .use(bodyParser())
 .use(router.routes())
 .use(router.allowedMethods())
 
 app.listen(3000,()=>{
 	console.log("ok")
 })
 //localhost://3000/100
 //界面1000,控制台也输出1000

# 嵌套路由

可以在应用中定义多个路由,然后把这些路由组合起来用,这样便于管理多个路由,也简化了路由的写法。

var forums = new Router();
var posts = new Router();

posts.get('/', function (ctx, next) {...});
posts.get('/:pid', function (ctx, next) {...});
forums.use('/forums/:fid/posts', posts.routes(), posts.allowedMethods());

// 可以匹配到的路由为 "/forums/123/posts" 或者 "/forums/123/posts/123"
app.use(forums.routes());

router.use()

# 路由前缀

通过 prefix 这个参数,我们可以为一组路由添加统一的前缀,和嵌套路由类似,也方便我们管理路由和简化路由的写法。不同的是,前缀是一个固定的字符串,不能添加动态参数。

var router = new Router({
  prefix: '/users'
});

router.get('/', ...); // 匹配路由 "/users" 
router.get('/:id', ...); // 匹配路由 "/users/:id"

# URL参数

koa-router 也支持参数,参数会被添加到 ctx.params 中。参数可以是一个正则表达式,这个功能的实现是通过 path-to-regexp 来实现的。原理是把 URL 字符串转化成正则对象,然后再进行正则匹配,之前的例子中的 * 通配符就是一种正则表达式。

router.get('/:category/:title', function (ctx, next) {
  console.log(ctx.params);
  // => { category: 'programming', title: 'how-to-node' } 
});

通过上面的例子可以看出,可以通过 ctx.params 去访问路由中的参数,使得能对参数做一些处理后再执行后续的代码。

# 接口权限设置

cookie认证和token认证

jsonwebtoken(JWT)

cnpm install --save jwt-simple
cnpm i koa-body -S
cnpm i --save koa-jwt
 const Koa = require('koa')
const Router = require('koa-router')
const jwt = require('jwt-simple')

const koaBody = require('koa-body')

const koaJwt = require('koa-jwt') //路由权限控制

const app = new Koa()
const  router = new Router()

//秘钥
const jwtSecret = 'jwtSecret'
const tokenExpiresTime = 1000 * 60 * 60 * 24 * 7

// Custom 401 handling if you don't want to expose koa-jwt errors to users
app.use(function(ctx, next){
    return next().catch((err) => {
        if (401 == err.status) {
            ctx.status = 401;
            ctx.body = 'Protected resource, use Authorization header to get access\n';
        } else {
            throw err;
        }
    });
});

app.use(koaJwt({secret:jwtSecret}).unless({
    path:[/^\/login/]
}))

router.get('/', (ctx) => {
    ctx.body = 'Hello koa-jwt'
})

// router.use(koaJwt(jwtSecret).unless({
//     path:[/^\/login/]
// }))

router.post('/login', koaBody(), (ctx) => {

    const user = ctx.request.body

    if (user && user.name){
        let payload = {
            exp:Date.now() + tokenExpiresTime,
            name:user.name
        }
        let token = jwt.encode(payload, jwtSecret)

        ctx.body = {
            user:user.name,
            code:1,
            token
        }
    }else {
        ctx.body = {
            code:-1
        }
    }
})

// router.use(koaJwt(jwtSecret))

router.get('/userInfo', ctx => {
    let token = ctx.header.authorization

    ctx.body = {
        token:token,
        user:ctx.state.user
    }

    //使用jwt-simple自行解析数据
   let payload = jwt.decode(token.split(' ')[1], jwtSecret);
    console.log(payload)
})

app.use(router.routes())
app.use(router.allowedMethods())

app.listen(3000, () => {
    console.log('app listening 3000...')
})
// curl -d 'name=lili&password=20' http://localhost:3000/login
/* {
	"user":"lili",
	"code":1,
	"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NTgwNjgx
	NTYwNjYsIm5hbWUiOiJsaWxpIn0.ty1fzvwDcDJhmYjUbbgo36aSCvIREFJ6FKvcSqmsefU"}*/

# 前端路由的概念

  • 前端路由分为hash路由,通过hashchange时间捕获hash变化。
  • history路由,通过popstate时间捕获url变化。
  • 内存路由:该方案一般适用于非浏览器环境如RN/测试等
最后更新: 11/16/2024, 8:21:19 AM