将 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 的支持:
- 在全球层面
- 在控制器级别
- 在行动层面
要在全局级别配置 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 的三个属性:
- Origins:您可以设置多个 origins 值,以逗号分隔。如果您希望任何来源向 API 发出 AJAX 请求,则将来源值设置为通配符值星号。
- Request Headers:Request header 参数指定允许哪些 Request header。允许任何 header 设置值到 *
- 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>
我已经将 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 的支持:
- 在全球层面
- 在控制器级别
- 在行动层面
要在全局级别配置 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 的三个属性:
- Origins:您可以设置多个 origins 值,以逗号分隔。如果您希望任何来源向 API 发出 AJAX 请求,则将来源值设置为通配符值星号。
- Request Headers:Request header 参数指定允许哪些 Request header。允许任何 header 设置值到 *
- 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>