【发布时间】:2021-09-28 23:01:38
【问题描述】:
重要编辑
我提到我可以直接从 Edge 或 Chrome 访问 API 端点,这是正确的。 但是,以下问题显然是 Edge 特有的(版本 91.0.864.71)。当我实际尝试通过 React 应用程序(使用 Axios)访问端点时,我得到了 200 响应和预期的数据。所以微软再次出击……这变成了一个“为什么这在 Edge 中不起作用”的问题。
我不能“只使用 Chrome”,因为我们公司强制要求使用 Edge,我不能反驳 Powers That Be 并告诉用户“只使用 Chrome”。
原始问题
我一直在互联网上从一边到另一边寻找有关此问题的见解,但到目前为止,我还没有找到任何可以提供解决方案的信息。
在这里工作的 Intranet 上,我创建了一个 .NET Core 5.0 Web API 并将其部署到 Windows 2012 R2 上的 IIS 8.5。 API “有效”,因为我可以从浏览器(Edge 或 Chrome)中点击它,并且我得到了我期望的响应正文。如果我提供 NTLM 凭据,我也可以从 Postman 中找到它——API 设置为使用 Windows 身份验证,并通过 IIS 控制台禁用匿名身份验证。
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
//Custom services for DI will go here.
services.AddScoped<IExceptionSearch, ExceptionSearch>();
services.AddAuthentication(IISDefaults.AuthenticationScheme);
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "PVSEXR", Version = "v1" });
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "PVSEXR v1"));
}
app.UseRouting();
app.UseAuthorization();
//Our custom logging middleware
app.UseAPILogging(Configuration["ConnectionStrings:LoggingConnection"], Configuration["AppSettings:DataGroupCode"]);
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
控制器方法示例
[Authorize]
[HttpGet("clients")]
public IActionResult GetClients()
{
//ReturnDataObject is a custom data transport wrapper
ReturnDataObject _rdo = _exceptionSearch.GetClients();
if (_rdo.OpStatus == "OK")
{
return Ok(JsonConvert.SerializeObject(_rdo));
}else if(_rdo.OpStatus == "MT")
{
return NoContent();
}
else
{
return BadRequest(JsonConvert.SerializeObject(_rdo));
}
}
正在 web.config 文件中设置 CORS,通过 IIS CORS 模块工作。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!-- To customize the asp.net core module uncomment and edit the following section.
For more info see https://go.microsoft.com/fwlink/?linkid=838655 -->
<system.webServer>
<handlers>
<remove name="aspNetCore" />
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath=".\PVSEXR.exe" arguments="" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="InProcess" />
<cors enabled="true">
<add origin="http://localhost:3000" allowCredentials="true">
<allowHeaders allowAllRequestedHeaders="true" />
</add>
</cors>
</system.webServer>
</configuration>
我有一个用于使用此服务的 ReactJS 应用程序。它目前正在使用 Axios 对端点执行 GET。 Axios 将 withCredentials 设置为 TRUE。
//Axios method
export const GetClients = () => {
return axios.get(`${process.env.REACT_APP_API_BASE}/pvsexr/exceptionsearch/clients`, {withCredentials: true});
}
//Method calling the Axios method
useEffect(()=>{
GetClients()
.then(result=>{
setClientList(result.data);
})
.catch(err=>{
console.log(err);
})
}, [])
我认为这就是我必须提供的所有代码,除非有人有特定要求。
问题是从 ReactJS 应用程序访问客户端端点时,我收到 401 Unauthorized 错误。因为我可以在浏览器中点击端点,并且可以通过提供 NTLM 凭据通过 Postman 访问它,所以看起来 API 状态良好。这留下了房子的 React 方面。我也尝试过使用普通的 ol' Fetch,但也得到了相同的 401 结果。
我错过了什么?我的开发机器已登录到域中,尽管 Web 服务器在不同的域中运行,但我认为存在信任关系,因为 Postman 允许我通过,无论我在该应用程序中使用哪个域。
谢谢!
编辑
添加了指示Axios方法返回Promise结构的代码,在需要处理的地方作为Promise处理。
【问题讨论】:
-
您的 axios 查询可以正常工作,但它会返回一个承诺;你的函数是同步的,因此承诺可能会挂起尝试类似
axios.get(<query_link>, {withCredentials: true}).then(res => return res.data).catch(err => alert(err))这样的事情,因此当承诺时它会返回所需的数据。 -
不过,我看不出这对 401 有什么影响。而且我没有发布调用这个方法的代码,它确实处理了承诺。
GetClients().then(result=>{ setClientList(result.data); }).catch(err=>{ console.log(err); })
标签: reactjs axios asp.net-core-webapi iis-8