我有一个带默认控制器的简单webapi项目。我需要使用ajax请求从html页面访问相同的值。
要求:
客户端:
以下是我的html页面,它有2个按钮。首先获取令牌并手动更新标题并使用第二个按钮获取值。
<html>
<head>
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#btnToken").click(function () {
var loginData = {
grant_type: 'password',
username: 'user1@gmail.com',
password: 'MyPassword'
};
$.ajax({
type: 'POST',
url: "http://172.16.2.19:8080/Token",
datatype: 'json',
data: loginData,
success: function (result) {
alert(JSON.stringify(result));
console.log(JSON.stringify(result));
},
error: function (error) {
alert(JSON.stringify(error));
}
});
});
function setHeader(xhr) {
xhr.setRequestHeader('Access-Control-Allow-Origin', '*');
xhr.setRequestHeader('Authorization', 'bearer 2wj036uRh7i2DpGAhzNOHuxb1TZcRWVkq_xU3mKGh6e4sO4hdwqaoJLeAAf_hoQewwYxnauUyFXev15oLOybwGDm-KDm-6TXvOSnby-7zYkN7UxNgHlna00hfure3VLYhPclZrQT591qWtH9oeIjc3AyXwJE7N_qhfZxvJKPUp5lTgzVJ9SBbTBOlyKnirUvJxwIrEwKABoNuRW6PbveTGs9i4osCI19mtkG53XB87-g2nwiWu2d2aw12WlT9ShFgf70cDgJMh84KY9eG4Mn9I1EJ2SgZI_i1CSoHktx5W6L8NbZqfv-Nd8qb_tjcw_eIJxZk7RSIDF2p42nVnUNXWJSivgcxNKaTr0KTlmK7PPYLtyyWNiIejZHDlXyBexy_Rmases9TGkIT5h1cpF8E3VNg7zMYCMAflJDYH_0Lj0siQ4QfNAYKB0D3hreEd3qW13YEpWcsGaR2uBI5Qc1l3N44Fyc_d-zLJP_lX8jhYE');
}
$("#btnData").click(function () {
$.ajax({
type: 'GET',
url: "http://172.16.2.19:8080/api/values",
content_type: 'application/json; charset=utf-8',
beforeSend: setHeader,
success: function (result) {
alert(JSON.stringify(result));
console.log(JSON.stringify(result));
},
error: function (error) {
alert(JSON.stringify(error));
}
});
});
});
</script>
</head>
<body>
<button id="btnToken" name="btnToken">Token</button>
<button id="btnData" name="btnData">Data</button>
</html>
了Serverside:
我在代码中启用了CORS,并在我的apiconfig中有以下内容
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
我还在glabal.asax中添加了预检请求,如下所示;
protected void Application_BeginRequest()
{
if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
{
Response.Headers.Add("Access-Control-Allow-Origin", "*");
Response.Headers.Add("Access-Control-Allow-Headers", "Access-Control-Allow-Origin, Origin, Content-Type, Authorization");
Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, DELETE, OPTIONS");
Response.Headers.Add("Access-Control-Max-Age", "1728000");
Response.End();
}
}
但是当我检查chrome时,我在控制台中收到以下错误。
请求时没有'Access-Control-Allow-Origin'标头 资源。因此,不允许原点'null'访问。
如果我使用IE,则错误看起来像
原始文件:在Access-Control-Allow-Origin标头中找不到。
我不知道我做错了什么
答案 0 :(得分:0)
您需要将EnableCostAttribute
个实例传递给EnableCors
方法:
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors); // <----
答案 1 :(得分:0)
打开文件App_Start / WebApiConfig.cs。将以下代码添加到WebApiConfig.Register方法。
using System.Web.Http;
namespace WebService
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// New code
config.EnableCors();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
接下来,将[EnableCors]属性添加到TestController类:
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Cors;
namespace WebService.Controllers
{
[EnableCors(origins: "*", headers: "*", methods: "*")]
public class TestController : ApiController
{
// Controller methods not shown...
}
}
如果您使用OAuthAuthorizationServerProvider,您可以尝试这样做:
public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
context.Validated();
return Task.FromResult<object>(null);
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
}
}