簡體   English   中英

從 Blazor WebAssembly (WASM) 項目調用外國 API(**不是** ASP.Net Core,托管)

[英]Call an foreign API from a Blazor WebAssembly (WASM) Project (**NOT** ASP.Net Core, hosted)

我創建了一個 Blazor WebAssembly-App (WASM) 作為 PWA。
它配置為 HTTPS 而不是ASP.NET 核心,托管。

我使用的代碼在控制台版本中進行了測試並且運行良好。

public void PostOnApi()
{
    HttpClient httpClient = new HttpClient();
    httpClient.DefaultRequestHeaders.Clear();
    httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
    var byteArray = Encoding.ASCII.GetBytes(GlobalData.userpassword);
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
       "Basic",
        Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes($"{GlobalData.username}:{GlobalData.password}"))
    );
        
    ClassForJSON InstanceOfClassForJSON = new ClassForJSON();
    string jsonString = JsonSerializer.Serialize(
        InstanceOfClassForJSON, 
        JsonOptions
    );

    StringContent content = new StringContent(
        jsonString
        System.Text.Encoding.UTF8,
        "application/json"
    );

    HttpResponseMessage response = httpClient.PostAsync(
        GlobalData.baseAdressOfApi,
        content
    ).Result;

    if (response.IsSuccessStatusCode)
    {
        object ResponseContent = JsonSerializer.Deserialize<object>(
            response.Content.ReadAsStringAsync().Result,
            JsonOptions
        );
        string tempResponse = JsonSerializer.Serialize(
            ResponseContent, 
            new JsonSerializerOptions { IncludeFields = true, WriteIndented = true }
        );

        ClassForResponseJSON InstanceOfClassForResponseJSON = JsonSerializer.Deserialize<ClassForResponseJSON>(tempResponse)!;
        string jsonResponse = JsonSerializer.Serialize(
            InstanceOfClassForResponse,
            new JsonSerializerOptions { IncludeFields = true, WriteIndented = true }
        );
        Console.WriteLine("[Success]: API-Call successful");
    }
    else
    {
        Console.WriteLine("[Error]: API-Call -> Validation? Authentification?");
    }
}

如果我現在在頁面的@code 部分調用此 function(頁面文件夾中的 API-Call.razor),則會拋出 Cors 錯誤。

Access to fetch at 'https://[Adress]' from origin 'https://localhost:5001' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

它可以使用以下代碼行修復:

WebAssemblyHttpRequestMessageExtensions.SetBrowserRequestMode(httpRequestMessage, BrowserRequestMode.NoCors);

當我上面的 function 改為 HttpRequestMessage 時:

StringContent content = new StringContent(
    jsonString,
    Encoding.UTF8,
    "application/json"
);

HttpRequestMessage httpRequestMessage = new HttpRequestMessage{
    RequestUri = new Uri(GlobalData.baseAdressOfApi);
    Content = content,
    Method = HttpMethod.Post 
};

WebAssemblyHttpRequestMessageExtensions.SetBrowserRequestMode(httpRequestMessage, BrowserRequestMode.NoCors);

HttpResponseMessage response = await client.SendAsync();
var responeContent = await response.Content.ReadAsStringAsync();

但是現在 Header 沒有Content-Type: application/json; charset=utf-8 Content-Type: application/json; charset=utf-8即我在StringContent content中設置的。 我認為這是因為,現在content (變量)被設置為 HttpRequestMessage 的主體部分,這是正確的嗎?


現在我真正的問題是:

  • 當 API 需要 (application/json) 和序列化類作為內容時,我該如何修改我的代碼,或者必須使用哪些類來設置 API 調用並獲得響應。
  • 我如何影響 RequestHeader(s)? 標頭對象中的任何修改都不會出現在傳出的 API 調用中(在本地端口上使用 NetCat 進行測試)
  • 我認為,要影響響應 header,您需要訪問 API,然后可以通過在 Access-Control-Allow-Headers 屬性中指定它們來將其配置為接受特定的標頭

    context.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Accept");

    其中上下文是 HttpContext。

    但是,如果您無法訪問源外 API,我認為唯一的方法是在源上使用代理,但也許有人知道一種方法。

    暫無
    暫無

    聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

     
    粵ICP備18138465號  © 2020-2024 STACKOOM.COM