1

我正在使用 LIFT 来提供 RESTful API,并且我希望此 API 允许使用 CORS(跨源资源共享)进行 POST 请求。我确实有 CORS 处理 GET 请求。

我遇到了麻烦,因为跨域 POST 首先在给定的 URL 上调用 OPTIONS,而我还没有弄清楚如何使用 LIFT 接受 OPTIONS 请求。

我的问题是:我需要混合或写入我的serve{}块,以便我可以允许 HTTP 动词 OPTIONS 用于 LIFT 中的给定路径?

现在使用 curl 我得到:

curl -X OPTIONS http://localhost:8080/path => [404]

我正在使用 LIFT 2.4-M5 和 Scala 2.9.1

编辑:根据pr1001的建议,我试图像这样扩展RestHelper

import net.liftweb.http.provider._
import net.liftweb.http._

trait RestHelper extends net.liftweb.http.rest.RestHelper {
    protected object Options {
        // Compile error here with options_?
        // because net.liftweb.http.Req uses LIFT's RequestType
        def unapply(r: Req): Option[(List[String], Req)] =
            if (r.requestType.options_?) Some(r.path.partPath -> r) else None
    }
}

@serializable
abstract class RequestType extends net.liftweb.http.RequestType {
    def options_? : Boolean = false
}

@serializable
case object OptionsRequest extends RequestType {
    override def options_? = true
    def method = "OPTIONS"
}

object RequestType extends net.liftweb.http.RequestType {
    def apply(req: HTTPRequest): net.liftweb.http.RequestType = {
        req.method.toUpperCase match {
            case "OPTIONS" => UnknownRequest("OPTIONS")
            case _ => net.liftweb.http.RequestType.apply(req)
        }
    }

    def method = super.method
}

我觉得这是我应该做的更多工作,因为我不想用我自己的 RequestType impl扩展Req 。

当谈到 Scala 时,我肯定处于较低的技能水平,所以我希望有人可以提供一个更简单的解决方案,因为我确信我缺少一些东西。

4

2 回答 2

1

你在使用RestHelper吗?如果是这样,您将指定要响应的请求类型并返回LiftResponseOptionRequest在传递给的部分函数中,Lift 中没有(尚未)使用,serve()但您应该能够使用自己的版本扩展RequestType 。使用UnknownRequest(如中UnknownRequest("OPTION"))也可以解决问题。

这可能也值得在邮件列表中提出,因为 CORS 支持将是一个有用的补充......

于 2012-04-05T20:15:24.883 回答
1

非常感谢 pr1001 的建议。我能够使它与以下内容一起工作:

import net.liftweb.http._

class RequestTypeImproved(requestType: RequestType) {
    def options_? : Boolean = requestType.method == "OPTIONS"
}

trait RestHelper extends net.liftweb.http.rest.RestHelper {
    implicit def req2ReqImproved(requestType: RequestType): RequestTypeImproved = {
        new RequestTypeImproved(requestType)
    }

    protected object Options {
        def unapply(r: Req): Option[(List[String], Req)] =
            if (r.requestType.options_?) Some(r.path.partPath -> r) else None
    }
}

然后:

serve {
    case req @ "path" Options _ => {
        LiftResponse(...)
    }
}
于 2012-04-06T20:34:53.790 回答