Доступ к выборке заблокирован политикой CORS — веб-сборка клиента Blazor

#c# #asp.net-core #cors #blazor #blazor-webassembly

#c# #asp.net-core #cors #blazor #blazor-webassembly

Вопрос:

У меня есть веб-сборка blazor, которая извлекается из внешнего API, построенного на ASP.NET Ядро, к которому у меня нет доступа. Я могу выполнять запросы get, но не могу выполнять запросы post. При выполнении я получаю следующую ошибку.

Доступ к выборке в ‘http://external:9000/User/Create » из источника «http://localhost:56138 ‘ заблокирован политикой CORS: ответ на предполетный запрос не проходит проверку контроля доступа: заголовок ‘Access-Control-Allow-Origin’ отсутствует на запрошенном ресурсе. Если непрозрачный ответ удовлетворяет вашим потребностям, установите режим запроса на «no-cors», чтобы получить ресурс с отключенным CORS.

Автор api подтверждает, что он разрешил cors разрешить любой заголовок в своем запуске, а также предложил мне сделать то же самое, но это не устранило проблему. Я подтвердил, что из отладчика я отправляю правильный формат данных, который требуется конечной точке, и я также использую схему http, такую же, как и веб-служба.

Это конфигурация клиента в program.cs

 builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri("http://external:9000/") });
builder.Services.AddCors(policy =>
{
   policy.AddPolicy("_myAllowSpecificOrigins", builder => builder.WithOrigins("http://external:9000/")
        .AllowAnyMethod()
        .AllowAnyHeader()
        .AllowCredentials());
   });
 

Вот как я публикую

 var dataJson = JsonConvert.SerializeObject(application);
var stringContent = new StringContent(dataJson, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync($"User/Create", stringContent);
 

Я читал, что это распространенная проблема со сборкой blazor, я не совсем уверен в том, что я прочитал. В настоящее время я пытаюсь переместить проект на сервер blazor, чтобы посмотреть, будет ли он работать, но я бы предпочел его на веб-сборке.

Комментарии:

1. Использование .AddCors(...) на клиенте мало что дает. Похоже, что другой автор может разрешить любой заголовок, но не любой метод. Проблема на сервере.

2. Но если вы не в состоянии исправить это, у сервера Blazor не должно быть этой проблемы.

3. @HenkHolterman Это именно то, что я подумал. Я был просто в отчаянии, чтобы добавить его.

4. Вы можете написать свой собственный уровень API в качестве посредника. Позволяет по-прежнему использовать Blazor Wasm.

5. @HenkHolterman Я запустил его на сервере Blazor. Я думаю, я просто буду придерживаться этого. И мне не нужно беспокоиться о том, что приложение не работает в некоторых браузерах, например, в проблемной веб-сборке

Ответ №1:

 builder.Services.AddCors(policy =>
{
   policy.AddPolicy("_myAllowSpecificOrigins", builder => builder.WithOrigins("http://external:9000/")
        .AllowAnyMethod()
        .AllowAnyHeader()
        .AllowCredentials());
   });
 

Эта настройка должна выполняться на сервере, и не на вашем, а на сервере внешнего API. Вы ничего не делаете в этом отношении, кроме вызова конечных точек в этом веб-Api.

Автор api подтверждает, что они разрешили cors разрешить любой заголовок в его запуске

Если это так, запросите у них код для подтверждения…

а также предложил мне сделать то же самое, но это не устранило проблему.

Вы ничего подобного не делаете.

Обходное решение:

ПОСКОЛЬКУ CORS является функцией безопасности JavaScript, обеспечиваемой браузером, вы можете обойти ее, вызвав код вашего сервера, из которого вы выполняете вызов этой конечной точки веб-Api, а затем возвращаете его обратно в интерфейс WebAssembly. Используйте асинхронный код столько, сколько сможете.

Обновление согласно комментарию

Вы хотите сказать, что у меня должно быть два проекта, сервер и клиент в рамках одного решения? Сервер вызывает вызовы внешнего API, а затем передает его клиенту. Это ваше последнее предложение?

Если вы используете приложение WebAssembly Blazor, размещенное на хостинговом сервере, содержащем контроллеры Web Api, то вам следует предоставить конечные точки, которые могут быть вызваны из вашего интерфейса WebAssembly. Код в этих конечных точках должен выполнять HTTP-вызовы внешнего веб-Api и передавать обратно в методы, вызывающие WebAssembly, данные, полученные от внешнего веб-Api.

Примечание: Если у вас нет таких контроллеров (они создаются по умолчанию Visual Studio), вы можете добавить их самостоятельно в проект сервера.

Если вы уже создали проект веб-Api вместо этих контроллеров, затем предоставьте необходимые конечные точки из вашего проекта веб-Api. Обратите внимание, что не имеет значения, находится ли ваш проект Web Api в том же решении интерфейса WebAssembly, если вы указываете правильный URL.

Если вы используете автономное приложение WebAssembly Blazor; то есть установка по умолчанию не создает серверный проект, вам нужно будет создать проект Web Api и использовать его, если вы его еще не создали.

Комментарии:

1. Вы хотите сказать, что у меня должно быть два проекта, сервер и клиент в рамках одного решения? Сервер вызывает вызовы внешнего API, а затем передает его клиенту. Это ваше последнее предложение?

2. Я обновил свой ответ, чтобы отразить ваш комментарий.

Ответ №2:

Вы работаете с localhost, поэтому вам следует использовать эту конфигурацию на своем сервере:

  builder.Services.AddCors(policy =>
{
   policy.AddPolicy("_myAllowSpecificOrigins", builder => 
    builder.WithOrigins("http://localhost:56138/")
     .SetIsOriginAllowed((host) => true) // this for using localhost address
     .AllowAnyMethod()
     .AllowAnyHeader()
     .AllowCredentials());
});
//
app.UseCors("_myAllowSpecificOrigins");