简体   繁体   English

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

[英]How to request cross domain with Aurelia using http-client

I have a simple Data Resource that retrieves a flat json file from within my own project. 我有一个简单的数据资源,可以从我自己的项目中检索一个扁平的json文件。 When I try to replace the url with that of a Working API end point that I have running on a separate domain I get a 401 (Unauthorized) error in chrome. 当我尝试将url替换为我在单独域上运行的Working API端点时,我在chrome中收到401(未授权)错误。

SETUP: I have a Visual Studio solution with two projects. 设置:我有一个包含两个项目的Visual Studio解决方案。

1) RateAppAPI (WebAPI Project w/ AspNet.cors ) 1) RateAppAPI (WebAPI项目与AspNet.cors
2) RateAppClient (ASPNET 5 Template w/ Aurelia ) 2) RateAppClient (带Aurelia的 ASPNET 5模板)
3) I have both a flat file and an API endpoint serving up the same json document. 3)我有一个平面文件和一个API端点,提供相同的json文档。 You will see one commented in the code and the other un-commented. 您将在代码中看到一个注释,另一个未注释。

  1. The API project is serving my GetAll route with no problems, I can hit the endpoint using postman and I get back a large result of Json. API项目正在为我的GetAll路由提供没有问题,我可以使用postman命中端点,并且我得到了Json的大量结果。 I have CORS enabled and setup properly, I have ruled that out as an issue. 我已启用CORS并正确设置,我已将此作为问题排除。
  2. I have the client project running Aurelia in the wwwroot directory and I am using aurelia-http-client which I will provide the code for, but I will tell you that the example I will provide works with no problems using the flat file that I have in a directory within the client project. 我有一个客户端项目在wwwroot目录中运行Aurelia,我正在使用aurelia-http-client ,我将提供代码,但我会告诉你,我将提供的示例使用我所拥有的平面文件没有问题在客户端项目中的目录中。
  3. As long as I point the Get() request at the flat file within my own project (of course) I have no issues pulling in the data and working with it. 只要我将Get()请求指向我自己项目中的平面文件(当然),我就没有问题可以提取数据并使用它。 It is only when I switch the url to point at the endpoint that is on a different domain that I get a 401 (Unauthorized) error. 只有当我将url切换到指向不同域上的端点时才会收到401(未授权)错误。

Here is my code (an ES6 Aurelia module) that is the Data Resource: 这是我的代码(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;
        });
    }
}

At the end of the day, I need to figure out how to use only Windows Auth and be able to run a client application from one domain, lets call that domain localhost:1234 and access a different domain, lets call the API domain localhost/RatAppAPI The API will have CORS enabled using the following method: 在一天结束时,我需要弄清楚如何只使用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 }
    );
}

在此输入图像描述

The first thing you should try is dropping the trailing forward slash in the origin. 你应该尝试的第一件事是在原点中删除正斜杠。 I am pretty sure that is what is causing some issues for you: 我很确定这是导致一些问题的原因:

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

Also assuming you are going to be hosting on IIS and you are looking to apply the same CORS policy globally to all your controller actions, then you can do it from the config as well: 另外假设您要在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>

Also the IIS Options handler may interfere with things, so make sure that it is removed ie IIS选项处理程序也可能会干扰事物,所以请确保它被删除,即

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

As a last resort you can also try disabling CORS security in chrome by either starting it with the following arguments --disable-web-security --user-data-dir or creating an alias in your host file for localhost and using that instead.This shouldn't really be required if all the headers have been set properly though. 作为最后的手段,您还可以尝试在chrome中禁用CORS安全性,方法是使用以下参数启动它们--disable-web-security --user-data-dir或在主机文件中为localhost创建别名并使用它。如果已经正确设置了所有标头,则不应该真正需要这样做。

Another thing, since you are looking to send through credentials, you won't be able to use a wildcard for the allowed domain. 另一件事,因为您希望通过凭据发送,您将无法使用通配符作为允许的域。 I guess that goes without saying :). 我想这不用说:)。 With that being said you may also need to do the following: 说到这一点,您可能还需要执行以下操作:

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

I ended up using the following in my API Global.asax 我最终在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();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM