如何使用 http-client 与 Aurelia 请求跨域

How to request cross domain with Aurelia using http-client

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

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

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

  1. API 项目正在为我的 GetAll 路由提供服务,没有任何问题,我可以 使用邮递员到达终点,我得到了一个很大的结果 Json。我已经启用并正确设置了 CORS,我已经排除了这种可能性 作为一个问题。
  2. 我在 wwwroot 目录中有客户端项目 运行ning 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 域 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 }
    );
}

您应该尝试的第一件事是删除原点中的尾部正斜杠。我很确定这就是导致您出现问题的原因:

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 启动它,或者在您的主​​机文件中为本地主机创建一个别名并使用该别名 instead.This 如果所有 headers 都已正确设置,则实际上不需要。

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

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

我最终在 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();
    }
}