WebAPI中的CORS问题

时间:2017-11-20 10:21:36

标签: javascript ajax asp.net-web-api cors

我有一个带默认控制器的简单webapi项目。我需要使用ajax请求从html页面访问相同的值。

要求:

  1. 使用令牌方法获取令牌
  2. 传递令牌并获取值
  3. 客户端:

    以下是我的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标头中找不到。

    我不知道我做错了什么

2 个答案:

答案 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[] { "*" });



        }
    }