WebApi中跨域解决办法

时间:2023-03-09 18:14:39
WebApi中跨域解决办法

在做Web开发中,常常会遇到跨域的问题,到目前为止,已经有非常多的跨域解决方案。由于时间有限,本文不会深入。

笔者遇到的问题是Js调用WebAPI中的数据进行跨域的场景。涉及若干跨域方案:

方案1:jsonp+回调

方案2:Microsoft.AspNet.WebApi.Cors提供的跨域属性

方案3:利用ACAO编写自定义Filter实现

一、关于方案一

方案1是同事提出来的,已经经过论证,并且自己研究过,是可行的。本质上是通过script标签动态加载js,还有callback机制。

但是,我个人觉得这个方案有些不足:

  1. 实现细节复杂,技术复杂性增大了不少,并且不好理解(服务器端、Web前端两头忙活)

  2. 只支持单向跨域

  3. 只支持Get,不支持Post等Http请求

  4. 扩展性不强

  5. 我在读参考文章时,感觉思路不清晰(至于是作者思路不清晰,还是写作思路不清晰,还是我个人理解能力不到位这个不好说。)

二、关于方案二

首先,我提出了方案2。当时在我看来,这个是比较合适的一个方案,接近完美。但是,它不可行。

原因在于:Microsoft.AspNet.WebApi.Cors的framework版本是4.5,而我们现有项目是4.0。我们的时间有限,几乎没有时间做深入研究。

三、关于方案三

我受方案2的启发,个人实现了方案3。方案3实现的最终效果接近方案2。支持:Global级别、Controller级别、Action级别。

方案三的缺点:因为“Access-Control-Allow-Origin”是HTML5中新增的特性,所以IE10以下浏览器不支持。

代码如下:

using System.Web.Http.Filters;
namespace MvcApplication1.CustomFilter
{
public class CrossSiteAttribute : ActionFilterAttribute
{
private const string Origin = "Origin";
private const string AccessControlAllowOrigin = "Access-Control-Allow-Origin";
private const string originHeaderdefault = "*";
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
actionExecutedContext.Response.Headers.Add(AccessControlAllowOrigin, originHeaderdefault);
}
}
}

服务器端代码示例:

        [CrossSite]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}

服务器端只需要把过滤器的标签[CrossSite]写上,服务器端就支持跨域了。省去了Web前端的处理和服务器端回调的处理。

当然,它很容易进行扩展。