WebAPI2 (OWIN) 上不允许使用 405 方法
405 Method Not Allowed on WebAPI2 (OWIN)
我正在为我的 API 设置一个 WebAPI 端点,但是我无法让我的 AngularJS 调用我的 PostRegister 方法工作。
网络API和Angular在不同的站点上。
在 Startup.cs 我有:
public void Configuration(IAppBuilder app)
{
ConfigureOAuth(app);
var config = new HttpConfiguration();
WebApiConfig.Register(config);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(config);
}
private void ConfigureOAuth(IAppBuilder app)
{
var oAuthServerOptions = new OAuthAuthorizationServerOptions
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString(Paths.TokenPath),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
Provider = Kernel.Get<IOAuthAuthorizationServerProvider>()
};
app.UseOAuthAuthorizationServer(oAuthServerOptions);
OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
app.UseOAuthBearerAuthentication(OAuthBearerOptions);
}
然后在控制器上,我将我的方法设置为允许匿名:
[AllowAnonymous]
public bool PostRegister(UserSignupForm form)
{
...
}
我也更新了 web.config:
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
在 Angular 方面,我进行了一个简单的 $http.post 调用:
saveRegistration: function (registration) {
return $http.post(baseUrl + '/api/signup/register', registration).then(function (response) {
return response;
});
}
当使用 Postman 进行调用时,我得到了成功的响应,但是当从 Angular 进行相同的调用时,我得到了 405 错误。
BitOfTech 示例站点正在发送相同的请求 headers,但能够获得 Access-Control-Allow-XXX headers
我已经更新我的代码以遵循 Token Based Authentication using ASP.NET Web API 2, Owin, and Identity
这听起来像是一个跨源问题。您应该安装 Fiddler 并检查 405 响应是否是由浏览器在您调用不同源上的资源时发出的飞行前请求(OPTIONS 动词)引起的。
请参阅这篇文章以获得对 CORS: http://www.html5rocks.com/en/tutorials/cors/
的很好解释
我认为您的 API 控制器上缺少注释,您应该在 API 控制器上添加注释,如
[RoutePrefix("api/signup")]
否则你的WebApiConfig
应该有像下面这样的路由定义
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
要设置 CORS,您始终需要在每次调用服务器时发送您的凭据。
然后,通过设置 $http 提供商默认选项,可以在 angular 中轻松执行此操作。
您可以在 angular 的配置阶段执行此操作。
代码
angular.module('myApp',[])
.config([
'$httpProvider',
function($httpProvider) {
$httpProvider.defaults.withCredentials = true;
}
]);
以上设置将在每个 $http 调用中添加凭据。
另请参阅 this post。有些什么同样的问题。
这可能有助于解决您的问题。
谢谢。
我最近遇到了类似的问题。我为飞行前 OPTIONS
请求添加了控制器处理程序,它解决了问题。
[AllowAnonymous]
[Route("Register")]
[AcceptVerbs("OPTIONS")]
public async Task<IHttpActionResult> Register()
{
return Ok();
}
您可能需要在您的应用程序中允许 cors 以进行响应 headers。下面是我在节点中所做的示例。
res.header('Access-Control-Allow-Origin', '*');
res.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS");
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
这可以帮助你。谢谢
问题不在于 angular。尽管您在 Postman 中得到响应,但在 angular 中请求没有给您响应不是问题。问题是默认情况下 Postman 没有 post Origin attribute
,这是测试 CORS 所需要的。 Chrome 默认情况下会阻止 Origin 属性,因此请求不会被视为来自不同的域。
那么如何在Postman中测试CORS
您需要一个具有相同名称 POSTMAN - Rest Client (Packaged App) 的不同 chrome 扩展,并使用其 'Request Interceptor toggle switch' 使其能够发送 ORIGIN 属性。
read here,节 restricted header
下面是您不发送 ORIGIN 属性时的示例屏幕截图
和相同的请求;发送 ORIGIN 属性时在 POSTMAN 中的响应
所以如果你看到,当你添加来源时,只有当你得到 ACCESS-CONTROL-* 属性作为响应时。
我希望这也能回答您关于
的问题
BitOfTech sample site, is sending the same request headers, but is
able to get the Access-Control-Allow-XXX headers"
网页Api部分
回到你的案例,你没有在 web-api 中启用 CORS。首先在 web-api 中启用 CORS。要在全球范围内启用 CORS,请使用
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var cors = new EnableCorsAttribute("www.example.com", "*", "*");
config.EnableCors(cors);
// ...
}
}
-- 你可以在网上找到很多关于如何在控制器级别添加它的资源等。
Angular部分
您首先需要确保 CORS 在 POSTMAN 中正常工作,然后尝试在 angular.
中访问 url
要在 angular 中启用 cors,您需要在 app.config() 函数中使用以下代码。
myApp.config(function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
});
注意:对于专家
Origin attributes is needed to test CORS.
这部分我不太确定,但根据我在 Postman 中看到的回复,情况似乎是这样。如果有人能阐明 Origin attribute
在 Cors.
中的角色,那就太好了
我正在为我的 API 设置一个 WebAPI 端点,但是我无法让我的 AngularJS 调用我的 PostRegister 方法工作。
网络API和Angular在不同的站点上。
在 Startup.cs 我有:
public void Configuration(IAppBuilder app)
{
ConfigureOAuth(app);
var config = new HttpConfiguration();
WebApiConfig.Register(config);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(config);
}
private void ConfigureOAuth(IAppBuilder app)
{
var oAuthServerOptions = new OAuthAuthorizationServerOptions
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString(Paths.TokenPath),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
Provider = Kernel.Get<IOAuthAuthorizationServerProvider>()
};
app.UseOAuthAuthorizationServer(oAuthServerOptions);
OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
app.UseOAuthBearerAuthentication(OAuthBearerOptions);
}
然后在控制器上,我将我的方法设置为允许匿名:
[AllowAnonymous]
public bool PostRegister(UserSignupForm form)
{
...
}
我也更新了 web.config:
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
在 Angular 方面,我进行了一个简单的 $http.post 调用:
saveRegistration: function (registration) {
return $http.post(baseUrl + '/api/signup/register', registration).then(function (response) {
return response;
});
}
当使用 Postman 进行调用时,我得到了成功的响应,但是当从 Angular 进行相同的调用时,我得到了 405 错误。
BitOfTech 示例站点正在发送相同的请求 headers,但能够获得 Access-Control-Allow-XXX headers
我已经更新我的代码以遵循 Token Based Authentication using ASP.NET Web API 2, Owin, and Identity
这听起来像是一个跨源问题。您应该安装 Fiddler 并检查 405 响应是否是由浏览器在您调用不同源上的资源时发出的飞行前请求(OPTIONS 动词)引起的。
请参阅这篇文章以获得对 CORS: http://www.html5rocks.com/en/tutorials/cors/
的很好解释我认为您的 API 控制器上缺少注释,您应该在 API 控制器上添加注释,如
[RoutePrefix("api/signup")]
否则你的WebApiConfig
应该有像下面这样的路由定义
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
要设置 CORS,您始终需要在每次调用服务器时发送您的凭据。 然后,通过设置 $http 提供商默认选项,可以在 angular 中轻松执行此操作。
您可以在 angular 的配置阶段执行此操作。
代码
angular.module('myApp',[])
.config([
'$httpProvider',
function($httpProvider) {
$httpProvider.defaults.withCredentials = true;
}
]);
以上设置将在每个 $http 调用中添加凭据。
另请参阅 this post。有些什么同样的问题。
这可能有助于解决您的问题。 谢谢。
我最近遇到了类似的问题。我为飞行前 OPTIONS
请求添加了控制器处理程序,它解决了问题。
[AllowAnonymous]
[Route("Register")]
[AcceptVerbs("OPTIONS")]
public async Task<IHttpActionResult> Register()
{
return Ok();
}
您可能需要在您的应用程序中允许 cors 以进行响应 headers。下面是我在节点中所做的示例。
res.header('Access-Control-Allow-Origin', '*');
res.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS");
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
这可以帮助你。谢谢
问题不在于 angular。尽管您在 Postman 中得到响应,但在 angular 中请求没有给您响应不是问题。问题是默认情况下 Postman 没有 post Origin attribute
,这是测试 CORS 所需要的。 Chrome 默认情况下会阻止 Origin 属性,因此请求不会被视为来自不同的域。
那么如何在Postman中测试CORS
您需要一个具有相同名称 POSTMAN - Rest Client (Packaged App) 的不同 chrome 扩展,并使用其 'Request Interceptor toggle switch' 使其能够发送 ORIGIN 属性。
read here,节 restricted header
下面是您不发送 ORIGIN 属性时的示例屏幕截图
和相同的请求;发送 ORIGIN 属性时在 POSTMAN 中的响应
所以如果你看到,当你添加来源时,只有当你得到 ACCESS-CONTROL-* 属性作为响应时。
我希望这也能回答您关于
的问题BitOfTech sample site, is sending the same request headers, but is able to get the Access-Control-Allow-XXX headers"
网页Api部分
回到你的案例,你没有在 web-api 中启用 CORS。首先在 web-api 中启用 CORS。要在全球范围内启用 CORS,请使用
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var cors = new EnableCorsAttribute("www.example.com", "*", "*");
config.EnableCors(cors);
// ...
}
}
-- 你可以在网上找到很多关于如何在控制器级别添加它的资源等。
Angular部分
您首先需要确保 CORS 在 POSTMAN 中正常工作,然后尝试在 angular.
中访问 url要在 angular 中启用 cors,您需要在 app.config() 函数中使用以下代码。
myApp.config(function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
});
注意:对于专家
Origin attributes is needed to test CORS.
这部分我不太确定,但根据我在 Postman 中看到的回复,情况似乎是这样。如果有人能阐明 Origin attribute
在 Cors.