Koa-Router : 如果请求不在 XHR 中,则跳过路由

问题描述

我有一个用 Koa 制作的 Rest API 和一些路由,但是,同时,它将服务于我的前端(制作带有 JS 框架和自己的路由器)。

事实是,当我从浏览器“localhost/user”访问时,我想显示前端,但是当我从 fetch/ajax/XMLHttpRequest 访问相同的 url 时,我想显示一个 JSON结果(Koa路由器给出的结果)。

所以我想仅在从 XHR 调用时才从 API 启用 /user 路由。

我的 isXMLHttpRequest 中间件是这样的:

AttributeRouteInfo.Name

然后,在我的 koa-router 中,我做了类似的事情:

module.exports = async (ctx,next) => {
    if(ctx.request.get('X-Requested-With') === 'XMLHttpRequest') {
        return next()
    }
}

然后,当我执行一些 XHR 请求时它可以工作,我按计划获得了 JSON,但是如果我尝试从浏览器访问 /user,API 会给我一个 Not Found 错误而不是我的前端.. .

如果请求不是在 XHR 中发出,我正在研究如何跳过 router.use 函数,但我找不到解决方案...

我认为它在中间件 else 条件下,我必须返回一些东西,但是我该怎么做才能跳过 koa-router 给我 404 ...

也许你能帮我?

解决方法

不确定我是否正确回答了您的问题。所以你有一个像静态 Web 服务器和 REST API 一样的后端,对吧?

我会尝试反过来做。使用例如 koa-static (https://www.npmjs.com/package/koa-static) 将首先尝试为您的文件提供服务,如果在您的定义公共目录中找不到匹配的文件,则处理所有其他路由(因此您的 REST API)。然后,您只需确保端点名称与您提供的文件不重叠。

,

好的,所以如果您对静态和 XMLHttpRequests 使用相同的路由(这可能不是最好的策略),那么这可以工作:

const Koa = require('koa')
const Router = require('koa-router')

const app = module.exports = new Koa();

isXmlRequest = (ctx) => {
    // here you could also compare e.g. "accept" header
    return (ctx.request.header && ctx.request.header['x-requested-with'] === 'XMLHttpRequest');
}

// static routes
const staticRouter = new Router()
staticRouter.get('/user',(ctx,next) => {
    ctx.body = 'OK from static route';
    next();
});

// XMLHttpRequest routes
const xmlRouter = new Router()
xmlRouter.get('/user',next) => {
    if (isXmlRequest(ctx)) {
        // serve it
        ctx.body = { ok: 'from JSON/XML' }
    } else {
        // downstream to next handler
        next();
    }
});

app.use(xmlRouter.routes());
app.use(staticRouter.routes());

const server = app.listen(3000)

这不是使用中间件 bwcause 这里你只能允许下游使用 next 但如果没有下一个,那么这会停止。没有 else ;-) 仅供参考