【问题标题】:How to request cross domain with Aurelia using http-client如何使用 http-client 向 Aurelia 请求跨域
【发布时间】:2016-08-25 05:40:55
【问题描述】:

我有一个简单的数据资源,可以从我自己的项目中检索一个平面 json 文件。当我尝试将 url 替换为在单独域上运行的工作 API 端点时,我在 chrome 中收到 401(未经授权)错误。

设置:我有一个包含两个项目的 Visual Studio 解决方案。

1) RateAppAPI(WebAPI 项目 w/AspNet.cors)
2) RateAppClient(带有Aurelia 的ASPNET 5 模板)
3) 我有一个 平面文件 和一个 API 端点 提供相同的 json 文档。您将在代码中看到一个已注释,而另一个未注释。

  1. API 项目正在为我的 GetAll 路由提供服务,没有任何问题,我可以 使用邮递员到达终点,我得到了很大的结果 杰森。我已经启用并正确设置了 CORS,我已经排除了 作为一个问题。
  2. 我在 wwwroot 目录中有运行 Aurelia 的客户端项目 我正在使用aurelia-http-client,我将提供代码 对于,但我会告诉你,我将提供的示例适用于 使用我在目录中的平面文件没有问题 客户项目。
  3. 只要我将 Get() 请求指向我自己项目中的平面文件(当然),我就可以毫无问题地提取数据并使用它。只有当我将 url 切换到指向不同域上的端点时,我才会收到 401(未经授权)错误。

这是我的代码(一个 ES6 Aurelia 模块),它是数据资源:

import {inject} from "aurelia-framework";
import {HttpClient} from "aurelia-http-client";

let baseURL = "http://localhost/RateAppAPI/api/UtilZip/ByUtil/7";
//let baseURL = "../api/utilzip/utilzip.json";

@inject(HttpClient)

export class UtilZipData {

constructor(httpClient) {
    this.http = httpClient;
    this.http.configure(x => { x.withCredentials(); });
}

getAll() {
    return this.http.get(baseURL)
        .then(response => {
            return response.content;
        });
    }
}

归根结底,我需要弄清楚如何仅使用 Windows Auth 并能够从一个域运行客户端应用程序,让我们调用该域 localhost:1234 并访问另一个域,让我们调用 API domain localhost/RatAppAPI API 将使用以下方法启用 CORS:

public static void Register(HttpConfiguration config)
{
    var cors = new EnableCorsAttribute("http://localhost:1234/", "*", "*");
    config.EnableCors(cors);
    config.MapHttpAttributeRoutes();

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
}

【问题讨论】:

  • 显然,关键问题是API端点授权。我不知道windows-authentication 可以进一步说明,但它不应该特定于Aurelia 或其http-client。希望此评论对像我这样发现它具有误导性的人有所帮助。
  • 我只是完整地描述了我在这里所做的事情。我不确定问题出在哪里。看起来这应该可以工作,但是在某个地方(在 API 中)或在客户端应用程序中,我在我的 http get 和 API 授权访问该端点之间做错了。
  • Eric,只需将尾部正斜杠放在允许的原点中,一切都应该开始工作......
  • 它正在工作,我将通过回顾和我学到的东西来更新问题。大声笑因为如果您在项目中多次启用 cors 并设置多个来源,这可能会非常棘手。

标签: javascript cors asp.net-web-api2 windows-authentication aurelia


【解决方案1】:

您应该尝试的第一件事是在原点中删除尾部正斜杠。我很确定这就是给您带来一些问题的原因:

var cors = new EnableCorsAttribute("http://localhost:1234/", "*", "*");
//Should be the following instead
var cors = new EnableCorsAttribute("http://localhost:1234", "*", "*");

还假设您将托管在 IIS 上,并且希望将相同的 CORS 策略全局应用于所有控制器操作,那么您也可以从配置中执行此操作:

<configuration>
    <system.webServer>
       <httpProtocol>
           <customHeaders>
               <add name="Access-Control-Allow-Origin" value="http://localhost:1234" />
               <add name="Access-Control-Allow-Methods" value="*" />
               <add name="Access-Control-Allow-Headers" value="*" />
           </customHeaders>
       </httpProtocol>
    </system.webServer>
</configuration>

此外,IIS 选项处理程序可能会干扰某些事情,因此请确保将其删除,即

<system.webServer>
    <handlers>
    ...
       <remove name="OPTIONSVerbHandler"/>
    ...
    </handlers>
</system.webServer>

作为最后的手段,您还可以尝试在 chrome 中禁用 CORS 安全性,方法是使用以下参数启动它 --disable-web-security --user-data-dir 或在您的主机文件中为 localhost 创建一个别名并使用它。不过所有的标题都已正确设置。

另外,由于您希望通过凭据发送,您将无法对允许的域使用通配符。我想这是不言而喻的:)。话虽如此,您可能还需要执行以下操作:

var cors = new EnableCorsAttribute("http://localhost:1234", "*", "*")
{
    SupportsCredentials = true
};

【讨论】:

  • 首先,感谢您抽出宝贵时间。我认为它是在 Web API 方面,但我不确定,这就是我给出完整故事的原因。删除正斜杠和仅将原点设置在一个地方的组合似乎是解决方案。让我做一些测试,然后我会回顾一下我的发现。
  • 没问题,我很乐意提供帮助。有时你只需要另一双眼睛就能发现这样的事情。
  • 我想更好地理解一切,我发现了一些有趣且令人困惑的反应,我什至关闭了 enable cors 并且能够运行我的客户端并使用该资源。很奇怪。但它正在工作。如果我提供一些图片和对我的发现的一些解释,你会瘦下来吗?
  • 当然,很高兴看到它。听起来有点奇怪,您可以在 CORS 关闭的情况下从客户端访问资源。您可能希望排除缓存作为其中的一部分。那些讨厌的 GET 请求喜欢被缓存:)
  • 当然。会检查的。
【解决方案2】:

我最终在我的 API Global.asax 中使用了以下内容

public void Application_BeginRequest(object sender, EventArgs e)
        {
    string httpOrigin = Request.Params["HTTP_ORIGIN"] ?? "*";

    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", httpOrigin);

    //HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, PUT");
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, dataType");
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");

    if (Request.HttpMethod == "OPTIONS")
    {
        HttpContext.Current.Response.StatusCode = 200;
        var httpApplication = sender as HttpApplication;
        httpApplication?.CompleteRequest();
    }
}

【讨论】:

    猜你喜欢
    • 2016-10-22
    • 2016-04-25
    • 2017-05-11
    • 1970-01-01
    • 2011-09-09
    • 2014-04-28
    • 1970-01-01
    • 2018-09-09
    • 2015-07-25
    相关资源
    最近更新 更多