4

我有一個簡單的數據資源,它可以從我自己的項目中檢索一個平面json文件。當我嘗試將url替換爲我在單獨的域上運行的工作API端點時,我在chrome中出現401(未授權)錯誤。如何使用http-client與Aurelia請求跨域域

SETUP:我有兩個項目的Visual Studio解決方案。

1)RateAppAPI(的WebAPI項目瓦特/ AspNet.cors
2)RateAppClient(ASPNET 5模板瓦特/ Aurelia
3)I兼得和API端點平面文件創建相同的json文檔。您會在代碼中看到一個評論,而另一個未評論。

  1. 的API項目的服務沒有問題我GETALL條路,我可以打 端點使用郵遞員,我回來 的JSON大型結果。我已啓用CORS並正確設置,我已經排除 作爲問題。
  2. 我在wwwroot目錄 運行Aurelia大街客戶端項目中,我使用aurelia-http-client,我將提供代碼 ,但我會告訴你,比如我將提供工程與 使用平面文件沒有問題,我有一個 客戶項目中的目錄。
  3. 只要我將Get()請求指向我自己的項目中的平面文件(當然),我沒有任何問題拉入數據並使用它。只有當我切換網址指向位於不同域的端點時,我會收到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驗證,並能從一個域運行客戶端應用程序,可以讓調用域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 } 
    ); 
} 

enter image description here

+0

顯然,關鍵的問題是API端點授權。我不知道'windows-authentication'可以進一步說明,但它不應該特定於Aurelia或其「http-client」。希望這個評論有助於那些發現像我這樣誤導人的人。 – qtuan

+0

我只是給了我在這裏做什麼的全貌。我不確定問題出在哪裏。看起來這應該可行,但在某處(在API中)或在客戶端應用程序中,我在http獲取和API授權訪問該端點之間做了一些錯誤。 –

+1

埃裏克,只是在您允許的原點放下尾隨的正斜槓,一切都應該開始工作...... – Shaun

回答

3

您應該嘗試的第一件事是放下原點的尾部正斜槓。我敢肯定這是什麼原因造成了一些問題,爲您提供:

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> 

作爲最後的手段,你也可以嘗試禁用CORS安全由鉻或者與下面的參數--disable-web-security --user-data-dir啓動它或創造本地主機的主機文件的別名和使用instead.This真不該如果所有標題都已正確設置,則需要使用該標題。

另一件事,因爲您希望通過憑據發送,所以您將無法爲允許的域使用通配符。我想這不用說:)。有了這樣說,你可能還需要做到以下幾點:

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

首先,謝謝你的時間。正如我認爲它是在Web API方面,但我不確定,這就是爲什麼我給出了完整的故事。拆除正斜槓和僅在一個地方設置原點的組合似乎是解決方案。讓我做一些測試,我會用復古的方式提供我的發現。 –

+0

沒問題,我非常樂意幫忙。有時候你只需要另一雙眼睛就可以發現這樣的東西。 – Shaun

+0

我想更好地理解所有內容,並且發現了一些有趣且令人困惑的回覆,我甚至關閉了啓用cors並能夠運行我的客戶端並使用該資源。很奇怪。但它正在工作。如果我主持了一些圖像並對我的發現進行了一些解釋,你會看一看嗎? –

0

最後我用我的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(); 
    } 
}