У меня есть Rest API, созданный с помощью Koa с некоторыми маршрутами, но в то же время он будет обслуживать мой Front (созданный с помощью JS framework и собственный роутер).

Дело в том, что когда я получаю доступ из браузера «localhost / user», я хочу отображать переднюю часть, но когда я достигаю того же URL-адреса из fetch / ajax / XMLHttpRequest , я хочу отобразить результат JSON ( один дал Коа-роутером).

Поэтому я хотел бы включить маршрут / user из API, только если он вызывается из XHR.

Я сделал свое промежуточное ПО isXMLHttpRequest следующим образом:

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

Затем в моем роутере koa я сделал что-то вроде:

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 выдает мне ошибку Not Found, а не мою переднюю часть ...

Я искал, как пропустить функцию router.use, если запрос не сделан в XHR, но я не могу найти решение ...

Я думаю, что это в состоянии промежуточного программного обеспечения else, я должен что-то вернуть, но что я могу сделать, чтобы koa-router не выдал мне 404 ...

Возможно ты можешь помочь мне ?

0
Simon Trichereau 10 Мар 2021 в 00:32

2 ответа

Лучший ответ

Хорошо, поэтому, если вы используете ОДИНАКОВЫЕ маршруты для static и 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)

Это не использует промежуточное ПО, потому что здесь вы можете разрешить только нисходящий поток с помощью next, но если следующего нет, то это останавливается. Нет else ;-) Просто для справки

0
Sebastian Hildebrandt 15 Мар 2021 в 14:32