将 cors 添加到 aspx web api 2 混合

adding cors to aspx web api 2 hybrid

我已经将 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 调用我的网站 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)
                    }
                });

            }

刚刚注意到一件对我来说有点奇怪的事情。当我 运行 网络 api 在本地(通过 visual studio)并将我的客户端 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,它为 null

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

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

Tools-> Nuget Package Manager ->Manage Nuget Packages for Solutions

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

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

  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

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

控制器级别

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

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

所以最后是 EnableCors 的属性

传递给 EnableCors 的三个属性:

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

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

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

更新

尝试将此配置添加到您的 web-config

<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>