【问题标题】:adding cors to aspx web api 2 hybrid将 cors 添加到 aspx web api 2 混合
【发布时间】:2016-07-08 08:04:01
【问题描述】:

我已将 Web API 2 添加到现有的 vb aspx Web 表单项目中。并且路由进入了全局 asax application_start,因为我没有像在标准 Web api 项目中那样使用 WebApiConfig 的 app_start 文件夹。我从 nugget 包管理器下载了 CORS 添加尝试启用 CORS

Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
        ' Fires when the application is started

       RouteTable.Routes.MapHttpRoute(
            name:="DefaultApi",
            routeTemplate:="api/{controller}/{id}",
            defaults:=New With {.id = RouteParameter.Optional}
        )

    Dim cors = New EnableCorsAttribute("*", "*", "*")
    GlobalConfiguration.Configuration.EnableCors(cors)

    End Sub

但是,每当我尝试运行一个通过 jquery ajax 调用我的 web api 的 html 页面时,我都会收到。

  Cross-Origin Request Blocked: The Same Origin Policy
 disallows reading the remote resource at https://xxxxx/specialdev/api/WSFobOrigin. 
(Reason: CORS header 'Access-Control-Allow-Origin' missing)

所以我不太确定我错过了什么,我也尝试将它添加到每个控制器。

Public Class WSFobOriginController
    Inherits ApiController
    <EnableCors("*", "*", "*")>
    <HttpGet>
    <CustomAuthentication>
    <Authorize(Roles:="WebService")>
    Public Function logon() As IHttpActionResult
        Return Ok("successfully loggon on")
    End Function

这里是 ajax 调用(我尝试过使用和不使用 crossDomain: true)

  this.logon = function () {
                $('#signin').prop('disabled', true);
                $.ajax({
                    url: "https://xxxxxxxx.dir.ad.dla.mil/specialdev/api/WSFobOrigin",
                    type: "GET",
                    datatype: "json",
                    crossDomain: true,
                    beforeSend: function (xhr) {
                        $('#logonSpinner').show();
                        xhr.setRequestHeader("Authorization", "Basic " + btoa(self.userName() + ":" + self.password()));
                    },
                    success: function (data) {
                        self.loggedon(true);
                    },
                    error: function (xhr, status, error) {
                        $('#signin').prop('disabled', false);
                        $('#logonSpinner').hide();
                        $('#logonError').show();
                        self.logOnErrorMessage("Status: " + xhr.status + " Message: " + xhr.statusText)
                    }
                });

            }

刚刚注意到一件对我来说有点奇怪的事情。当我在本地(通过visual studio)运行web api并将我的客户端jquery ajax调用更改为本地url时它可以工作。

URL Protocol    Method  Result  Type    Received    Taken   Initiator   Wait‎‎  Start‎‎ Request‎‎   Response‎‎  Cache read‎‎    Gap‎‎
http://localhost:52851/api/WSFobOrigin  HTTP    OPTIONS 200     420 B   31 ms   CORS Preflight  0   16  0   15  0   203

和

URL Protocol    Method  Result  Type    Received    Taken   Initiator   Wait‎‎  Start‎‎ Request‎‎   Response‎‎  Cache read‎‎    Gap‎‎
http://localhost:52851/api/WSFobOrigin  HTTP    GET 200 application/json    447 B   218 ms  XMLHttpRequest  16  15  203 0   0   0

但是当我将客户端更改为指向实际服务器时,预检中止并且类型不再显示 OPTIONS 它为空

URL Protocol    Method  Result  Type    Received    Taken   Initiator   Wait‎‎  Start‎‎ Request‎‎   Response‎‎  Cache read‎‎    Gap‎‎
https://xxxxxxx.dir.ad.dla.mil/specialdev/api/WSFobOrigin   HTTPS       (Aborted)       0 B 47 ms   CORS Preflight  0   47  0   0   0   796

其他一些帖子建议添加我尝试过的过滤器,但似乎也不起作用

导入 System.Web.Http.Filters

Public Class AllowCors
    Inherits ActionFilterAttribute
    Public Overrides Sub OnActionExecuted(actionExecutedContext As HttpActionExecutedContext)
        If actionExecutedContext Is Nothing Then
            Throw New ArgumentNullException("actionExecutedContext")
        Else
            actionExecutedContext.Response.Headers.Remove("Access-Control-Allow-Origin")
            actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin", "*")
            actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type")
            actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Methods", "GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS")
        End If
        MyBase.OnActionExecuted(actionExecutedContext)
    End Sub
End Class

并用allowcors装饰我的控制器

    <AllowCors>
    <EnableCors("*", "*", "*")>
    <HttpGet>
    <CustomAuthentication>
    <Authorize(Roles:="WebService")>
    Public Function logon() As IHttpActionResult
        Return Ok("successfully loggon on")
    End Function

但仍然没有运气

status: 404
Method:  OPTIONS
Request Headers: Host: xxxxxx.dir.ad.dla.mil
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: null
Access-Control-Request-Method: GET
Access-Control-Request-Headers: authorization
Connection: keep-alive

Response Headers:  Cache-Control: private
Content-Type: text/html
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
X-Frame-Options: SAMEORIGIN
Date: Wed, 23 Mar 2016 16:53:06 GMT
Content-Length: 1245

【问题讨论】:

  • 您能否在解决方案结构中的App_code 中找到Startup.cs?因为你提到你正在使用 web api2
  • 不,这是怎么回事,因为我们有一个现有的 aspx web 表单应用程序,我进入 nu get 并在事后添加到 web api 包中。所以我没有像你通常那样得到典型的 app_start 文件夹,它有 bundle_config、route_config 等。相反,路由等进入 application_start 下的全局 asax(请参阅我帖子中的第一个代码块)。另一个令人讨厌的是 VB 应用程序,使用 vb 查找 web api 示例一直很困难。
  • 你可以显示你的webconfig,并尝试在Application_Start中以var context = HttpContext.Current; var response = context.Response; // enable CORS response.AddHeader("Access-Control-Allow-Origin", "*"); response.AddHeader("X-Frame-Options", "ALLOW-FROM *");这种方式启用cors
  • 您是否尝试将启用 cors 代码移动到路由上方的函数顶部?
  • 尝试将启用 cors 移动到路由上方,还尝试将添加标头添加到全局 asax,但它抱怨我运行时有重复的标头。

标签: asp.net vb.net cors asp.net-web-api2


【解决方案1】:

您可以在三个级别为 Web API 配置 CORS 支持:

  1. 在全球层面
  2. 在控制器级别
  3. 在行动层面

要在全局级别配置 CORS 支持, 首先安装 CORS 包(你已经做了) 然后从 App_Start 文件夹中打开 WebApiConfig.cs 文件。(这里你说你没有那个文件夹)

Dim cors = New EnableCorsAttribute("http://localhost:5901", "*", "*")
config.EnableCors(cors)

(由于你没有使用那个方法,那么我们将进入下一个级别)

动作级别

    <EnableCors(origins := "*", headers := "*", methods := "*")> 
  <HttpGet>
    <CustomAuthentication>
    <Authorize(Roles:="WebService")>
 Public Function logon() As IHttpActionResult
        Return Ok("successfully loggon on")
    End Function

在上述方法中,您需要设置参数以允许所有标头并通过将值设置为星号来支持所有HTTP方法。

控制器级别

<EnableCors(origins := "*", headers := "*", methods := "*")> _
Public Class ClassesController
    Inherits ApiController
End Class

在此您需要设置参数以允许所有标头并通过将值设置为星号来支持所有 HTTP 方法。您可以使用 [DisableCors] 属性从 CORS 支持中排除其中一项操作。

所以最后这里是EnableCors的属性

有三个属性传递给 EnableCors:

  1. Origins:您可以设置多个以逗号分隔的 origins 值。如果您希望任何来源向 API 发出 AJAX 请求,请将来源值设置为通配符值星。
  2. 请求标头:请求标头参数指定允许哪些请求标头。允许任何标头设置值为 *
  3. HTTP 方法:methods 参数指定允许哪些HTTP 方法访问资源。要允许所有方法,请使用通配符值“*”。否则设置逗号分隔的方法名称以允许一组方法访问资源。

所以在VB中结合以上几点你需要声明如下

<EnableCors(origins := "http://localhost:XXX,http://localhost:YYYY", headers := "*", methods := "POST,GET")> _
Public Class ClassesController
    Inherits ApiController
End Class

更新

尝试将此配置添加到您的网络配置中

<customHeaders> 
<add name="Access-Control-Allow-Origin" value="*" /> 
<add name="Access-Control-Allow-Methods" value="GET, PUT, POST, DELETE, HEAD, OPTIONS" /> 
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" /> 
<add name="Access-Control-Allow-Headers" value="Content-Type, Accept, Authorization" /> 
</customHeaders>

【讨论】:

  • 感谢您的建议,我已经在所有三个级别上设置了 CORS,(以及添加自定义过滤器参见原始帖子)我看到一些帖子建议将标头添加到 server.config 但是我不允许更改该配置文件。当我在本地主机上运行时,一切正常。 (客户端在我的桌面或其他 Visual Studio 解决方案上运行,并指向在本地主机上运行的 Web api)CORS 在进入“真实”服务器时被阻止。是否有可能阻止我的 iis 7.5 服务器设置?
  • @user2744722 尝试在与 IIS 相关的 webconfig &lt;configuration&gt; &lt;system.webServer&gt; &lt;httpProtocol&gt; &lt;customHeaders&gt; &lt;add name="Access-Control-Allow-Origin" value="*" /&gt; &lt;/customHeaders&gt; &lt;/httpProtocol&gt; &lt;/system.webServer&gt; &lt;/configuration&gt; 设置中给出这个
  • 所以这可以进入 web.config 吗?不是 server.config?因为我不允许更改 server.config
  • @user2744722 此代码位可能是错误的xhr.setRequestHeader("Authorization", "Basic " + btoa(self.userName() + ":" + self.password())); 此处当您观察您在网络中发布的响应时,其标头已更改为“访问控制请求标头:授权”请检查它也是。如果你想添加授权,请尝试找到一些过程而不是更改标题
  • @user2744722 是的,在 web-config 中进行
【解决方案2】:

我想你忘了添加 Microsoft.AspNet.Cors。如果你使用 Visual Studio,你可以这样添加使用:

工具-> Nuget 包管理器->管理用于解决方案的 Nuget 包

你应该找到 Microsoft.AspNet.Cors 并安装到 api 项目

【讨论】:

  • 好的。 EnableCors() 可能是错误的,config.MapHttpAttributeRoutes(); var cors = new EnableCorsAttribute("", "", "*"); config.EnableCors(cors);我的 Web API 配置。如果你想试试这个
猜你喜欢
  • 1970-01-01
  • 2018-03-21
  • 1970-01-01
  • 2017-04-28
  • 2016-06-10
  • 2013-09-08
  • 2014-10-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多