如何在 Fantom / afBedSheet REST 服务中启用跨源资源共享 (CORS)?

How to enable Cross Origin Resource Sharing (CORS) in a Fantom / afBedSheet REST service?

我正在使用 Fantom and afBedSheet 开发 REST API。我需要允许 cross-origin 资源共享,以便我可以通过 AJAX 从 UI 调用我的 RESTful 服务,后者在不同端口的不同 Web 容器上运行。

我目前在请求处理程序方法中这样做:

    res.headers["Access-Control-Allow-Origin"] = "http://localhost:8080"

但是随着 API 的增长和请求处理程序数量的增长,它不再实用。我想知道如何在每个响应中注入 header 。我用谷歌搜索了这个问题,但只找到了对 very old version of afBedSheet 中似乎不再相关的文档的引用。谁能举个例子好吗?

CORS 必须手动设置,但如前所述,这并不难。任何在请求处理程序方法中变得重复的东西通常都可以藏在某个地方,设置 HTTP 响应 headers 也不例外。这些可以通过 BedSheet Middleware:

设置
using afIoc
using afBedSheet

const class CorsMiddleware : Middleware {
    @Inject private const HttpRequest           req
    @Inject private const HttpResponse          res
    @Inject private const ResponseProcessors    processors

    new make(|This|in) { in(this) } 

    override Void service(MiddlewarePipeline pipeline) {
        // echo back in the response, whatever was sent in the request
        res.headers["Access-Control-Allow-Origin"]  = req.headers["Origin"]
        res.headers["Access-Control-Allow-Methods"] = req.headers["Access-Control-Request-Method"]
        res.headers["Access-Control-Allow-Headers"] = req.headers["Access-Control-Request-Headers"]

        // deal with any pre-flight requests
        if (req.httpMethod == "OPTIONS")
            processors.processResponse(Text.fromPlain("OK"))
        else
            pipeline.service
    }
}

请注意,以上内容将在 所有 请求上启用 CORS - 这对开发人员来说很方便,但对于实时代码,您应该更加挑剔并验证任何给定的来源、方法和 Headers.

床单 Middleware 应贡献给 MiddlewarePipeline 服务:

@Contribute { serviceType=MiddlewarePipeline# }
static Void contributeMiddleware(Configuration config) {
    config.set("myApp.cors", config.autobuild(CorsMiddleware#)).before("afBedSheet.routes")
}

请注意,CorsMiddleware 之前 BedSheet 路由中插入管道以确保它被执行。