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

Koa-Router : Skip the route if the request not in XHR

我有一个用 Koa 制作的 Rest API 和一些路线,但是,同时,它将serve my Front(使用 JS 框架和自己的路由器制作)。

事实是,当我从浏览器访问“localhost/user”时,我想显示前面但是当我从 fetch / [=40 到达相同的 url 时=] / XMLHttpRequest 我想显示一个 JSON 结果(Koa-router 给出的结果)。

所以我想启用来自 API 的 /user 路由,仅当它是从 XHR 调用时。

我是这样做我的 isXMLHttpRequest 中间件的:

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

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

const Router = require('koa-router')

const isXMLHttpRequest = require("@middlewares/isXMLHttpRequest")

const router = new Router()

const user = require("@routes/user")
router.use('/user', isXMLHttpRequest, user.routes(), user.allowedMethods())

然后,当我做一些 XHR 请求时它起作用了,我按计划有 JSON,但是如果我尝试从浏览器访问 /user,API 给了我未找到错误而不是我的前面...

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

我认为它处于 middleware else 状态,我必须 return 一些东西,但是我能做些什么来跳过 koa-router 给我 404 ...

也许你能帮帮我?

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

我会尝试反过来做。使用例如 koa-static (https://www.npmjs.com/package/koa-static) 将首先尝试为您的文件提供服务,如果在您的 defines public 目录中没有找到匹配的文件,则所有其他路由(因此您的 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', (ctx, 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 ;-) 仅供参考