【发布时间】:2013-03-17 12:30:06
【问题描述】:
我有一个使用 NancyFX 制作的 API 服务,并且有几个前端开发人员针对这个 API 创建了一个 SPA JS 客户端。
我们希望针对已发布的服务器测试客户端代码,而不必过于频繁地发布客户端代码。
但是,客户端在本地主机上运行,而服务器在 Windows Azure 上。
在 NancyFX 服务器上启用 CORS 是否可行且容易?我该怎么做?
谢谢。
【问题讨论】:
我有一个使用 NancyFX 制作的 API 服务,并且有几个前端开发人员针对这个 API 创建了一个 SPA JS 客户端。
我们希望针对已发布的服务器测试客户端代码,而不必过于频繁地发布客户端代码。
但是,客户端在本地主机上运行,而服务器在 Windows Azure 上。
在 NancyFX 服务器上启用 CORS 是否可行且容易?我该怎么做?
谢谢。
【问题讨论】:
在 Nancy 的引导程序中可以做到这一点
protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context)
{
//CORS Enable
pipelines.AfterRequest.AddItemToEndOfPipeline((ctx) =>
{
ctx.Response.WithHeader("Access-Control-Allow-Origin", "*")
.WithHeader("Access-Control-Allow-Methods", "POST,GET")
.WithHeader("Access-Control-Allow-Headers", "Accept, Origin, Content-type");
});
【讨论】:
WithHeader("Access-Control-Allow-Methods", "POST,GET") 你允许你需要的方法。
如果您使用 IIS 来托管 Nancy,在这种情况下是在 Windows Azure 上,那么您只需更新 web.config 以将标头添加到每个请求。
这可以通过添加以下内容来完成:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
您也可以按照 Sunny 的建议进行操作,如果您不喜欢每次都这样写,您可以添加自己的扩展方法:
public static class NancyExtensions
{
public static void EnableCors(this NancyModule module)
{
module.After.AddItemToEndOfPipeline(x =>
{
x.Response.WithHeader("Access-Control-Allow-Origin", "*");
});
}
}
然后你可以在你的路由中调用this.EnableCors()。
【讨论】:
var origin = Request.Headers["Origin"].FirstOrDefault(); 获取来源,然后只允许特定域使用端点。
如果你的 HTTP 请求是simple 那么Phill's answer 就足够了,但是如果请求不是那么简单,浏览器会发送一个预检检查。预检检查是一个 OPTIONS HTTP 请求,这也必须处理。
这是配置CORS的扩展方法:
public static class MyNancyExtension
{
public static void EnableCORS(this Nancy.Bootstrapper.IPipelines pipelines)
{
pipelines.AfterRequest.AddItemToEndOfPipeline(ctx =>
{
if (ctx.Request.Headers.Keys.Contains("Origin"))
{
var origins = "" + string.Join(" ", ctx.Request.Headers["Origin"]);
ctx.Response.Headers["Access-Control-Allow-Origin"] = origins;
if (ctx.Request.Method == "OPTIONS")
{
// handle CORS preflight request
ctx.Response.Headers["Access-Control-Allow-Methods"] =
"GET, POST, PUT, DELETE, OPTIONS";
if (ctx.Request.Headers.Keys.Contains("Access-Control-Request-Headers"))
{
var allowedHeaders = "" + string.Join(
", ", ctx.Request.Headers["Access-Control-Request-Headers"]);
ctx.Response.Headers["Access-Control-Allow-Headers"] = allowedHeaders;
}
}
}
});
}
}
要启用 CORS,请在引导程序中调用此扩展方法:
protected override void ApplicationStartup(Nancy.TinyIoc.TinyIoCContainer container, Nancy.Bootstrapper.IPipelines pipelines)
{
base.ApplicationStartup(container, pipelines);
pipelines.EnableCORS();
}
请注意,它没有扩展 NancyModule,因为 OPTIONS is handled outside of module(也是 here)。
【讨论】: