Koa.js - 提供静态文件和 REST API

问题描述 投票:0回答:5

我是 koa.js 库的新手,我需要一些帮助。我正在尝试使用 koa 制作简单的 REST 应用程序。 我有一个静态 html 和 javascript 文件,我想在路线

/
上提供服务,并从
/api/
访问 REST API。

这是我的项目目录树:

project
├── server
│   ├── node_modules
│   ├── package.json
│   └── src
│       ├── config
│       ├── resources
│       └── server.js
├── ui
│   ├── app
│   ├── bower.json
│   ├── bower_components
│   ├── dist
│   ├── node_modules
│   ├── package.json
│   └── test

这是我的来源:

var app = require('koa')();
app.use(mount('/api/places', require('../resources/places')));

// does not work
var staticKoa = require('koa')();
staticKoa.use(function *(next){
  yield next;
  app.use(require('koa-static')('../ui/app', {}));
});
app.use(mount('/', staticKoa));

// does not work
app.use(mount('/', function*() {
    app.use(require('koa-static')('../ui/app/', {}));
}));

// does not work
app.use(mount('/', function*() {
    app.use(require('koa-static')('.', {}));
}));
// GET package.json -> 404 not found

我尝试过

koa-static
koa-static-folder
koa-static-server
库,但都不起作用,所以我做错了。

我已经尝试过这个并且它有效,但我无法访问我的 REST api:

var app = require('koa')();
app.use(require('koa-static')('../ui/app/', {}));
javascript node.js rest static koa
5个回答
24
投票

我有点难以理解您在示例代码中所做的事情...... 这是一个简单的例子,可以完成您想要的一切:

'use strict';
let koa     = require('koa'),
    send    = require('koa-send'),
    router  = require('koa-router')(),
    serve   = require('koa-static');

let app = koa();
// serve files in public folder (css, js etc)
app.use(serve(__dirname + '/public'));

// rest endpoints
router.get('/api/whatever', function *(){
  this.body = 'hi from get';
});
router.post('/api/whatever', function *(){
  this.body = 'hi from post'
});

app.use(router.routes());

// this last middleware catches any request that isn't handled by
// koa-static or koa-router, ie your index.html in your example
app.use(function* index() {
  yield send(this, __dirname + '/index.html');
});

app.listen(4000);

5
投票
const root = require('path').join(__dirname, 'client', 'build');
app.use(serve(root));

app.use(async ctx => {
    await send(ctx, `/index.html`, {
        root
    });
});

3
投票

来自评论中的@Nurpax:

app.use(async function (ctx, next) {
  return send(ctx, '/index.html', { root: paths.client()
})
.then(() => next()) }) 

关键是要指定

{root:<some path>}
。我认为我的情况的问题是出于安全原因,发送不允许相对路径或项目树之外的路径。指定根参数,然后给出相对于此的文件名似乎可以解决问题。我想我希望 koa-send 在节点输出上记录有关此的错误/警告。


0
投票

这段代码对我来说工作得很好。

我正在 koa 中提供自动文件图像和视频。

const koa = require('koa');
const koaRouter = require('koa-router');
const cors = require('@koa/cors');
const koaBody = require('koa-bodyparser');
const koaSend = require('koa-send'); 
const serve = require('koa-static');
const app = new koa();
const router = new koaRouter();

router.get('/public/audios/:item', async ctx => {
    const { item } = ctx.params;
    await koaSend(ctx, { root: `./public/audios/${item}` });
});

router.get('/public/videos/:item', async ctx => {
    const { item } = ctx.params;
    await koaSend(ctx, { root: `./public/videos/${item}` });
})

router.get('/public/images/:item', async ctx => {
    const { item } = ctx.params;
    await koaSend(ctx, { root: `./public/images/${item}` });
})

app
  .use(serve('./public'))
  .use(koaBody({ jsonLimit: '100mb', formLimit: '100mb', textLimit: '100mb' }))
  .use(cors())
  .use(router.routes())
  .use(router.allowedMethods())

app.listen(3000);

0
投票

我最终做了什么:

import * as fs from "fs";

myrouter.get("/data/:name", async (ctx, next) => {
    ctx.body = fs.createReadStream(`./data/${ctx.params.name}`);
});

但是请注意,输入

path/../../../some/path
可以绕过根路径。

© www.soinside.com 2019 - 2024. All rights reserved.