Проблема CORS, когда angular и web API(.NET core) используется [решено]
У меня есть два отдельных проекта, Один из которых WebAPI разработан в .net Core 2.2 с аутентификацией Windows, а другой-Angular. Я застрял в вопросе CORS. Я смог обработать запрос GET с помощью withCredentials: true в опции метода GET, как указано ниже, где httpClient - это импорт { HttpClient } из '@angular/common/http':
httpClient.get('url'), { withCredentials: true }) as Observable<Type>;
Но в случае POST запрос идет как опция. И каждый раз он терпит неудачу с кодом ошибки 401 UNAUTHORIZED на вкладке Network окна Chrome Developer Tools. И в консоли он показывает следующую ошибку
Доступ к XMLHttpRequest по адресу 'http://localhost:5000/api/xxx/xxxMethod" от происхождения "http://localhost:4200' был заблокирован политикой CORS: ответ на предполетный запрос не проходит проверку контроля доступа: он не имеет статуса HTTP ok.
Что я уже пробовал:
Чтобы решить эту проблему, я внес несколько изменений в следующие файлы Web API и Angular project:
Веб.конфиг:Я добавил приведенный ниже код под тегом system.webserver
<handlers> <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" /> <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> <remove name="OPTIONSVerbHandler" /> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> </handlers> <httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="http://localhost:4200" /> <add name="Accept" value="application/json, text/plain, */*"/> </customHeaders> </httpProtocol>
PreflightRequestMiddleware.в CS: Я создал это промежуточное программное обеспечение для обработки всех входящих запросов и обхода запроса опций со статусом OK
public class PreflightRequestMiddleware { private readonly RequestDelegate Next; public PreflightRequestMiddleware(RequestDelegate next) { Next = next; } public Task Invoke(HttpContext context) { return BeginInvoke(context); } private Task BeginInvoke(HttpContext context) { context.Response.Headers.Add("Access-Control-Allow-Credentials", new[] { "true" }); context.Response.Headers.Add("Access-Control-Allow-Headers", new[] { "Origin, X-Requested-With, Content-Type, Accept, Athorization, ActualUserOrImpersonatedUserSamAccount, IsImpersonatedUser" }); context.Response.Headers.Add("Access-Control-Allow-Methods", new[] { "GET, POST, PUT, DELETE, OPTIONS" }); if (context.Request.Method == HttpMethod.Options.Method) { context.Response.StatusCode = (int)HttpStatusCode.OK; return context.Response.WriteAsync("OK"); } return Next.Invoke(context); } } public static class PreflightRequestExtensions { public static IApplicationBuilder UsePreflightRequestHandler(this IApplicationBuilder builder) { return builder.UseMiddleware<PreflightRequestMiddleware>(); } }
Автозагрузки.в CS:
public void ConfigureServices(IServiceCollection services) { services.AddCors(o => o.AddPolicy("CorePolicy", builder => { builder.AllowAnyMethod(); })); ....... } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UsePreflightRequestHandler(); ..... app.UseCors("CorePolicy"); //Tried to put this first line too, but no luck ..... }
Then in Angular Project, for POST method call I first create headers: <pre lang="TypeScript"> HttpHeaders() with below values: 'Content-Type', 'application/json' 'Content-Type', 'application/json' 'Accept-Language', ['en-US', 'en', 'q=0.9'] 'Accept', ['application/json', 'text/plain', '*/*'] 'Athorization', 'Include' Calling POST Method client.post(url, postParam, optionsWithHeader).pipe( map((response: any) => response as Result[]), catchError(#HandleError)
Но есть одна странная вещь, которую я заметил, Когда я сначала запускаю Fiddler, а затем запускаю Web API и Angular app, все запросы опций обрабатываются в PreflightRequestMiddleware. Но когда я бегу без скрипача, запрос даже не доходит до PreflightRequestMiddleware. Я провел 4 дня, но до сих пор понятия не имею, что случилось. Мало кто может предложить мне проверить заголовок, который получается при запуске Fiddler in Request, но я тоже попробовал это сделать, но безуспешно. У кого-нибудь есть хоть малейшая зацепка??
Mahadevan Annamalai
Решение 1 - это решение моей проблемы. Спасибо за сообщение.