在我的HttpServive
中,我共享了http方法,用于处理开始/结束加载栏,为JWT设置正确的标题,等等。
一切都很好,但现在我试图在catch
中添加一些逻辑来检查非200状态代码(例如401)的响应,以便我可以做一些事情然后重新制作失败的请求。
问题是,无论出于何种原因,无法从catch
访问非200状态代码时返回的响应。
例如,这是代码:
// ...
return this.http[method](url, options || defaultOptions)
.map((res: Response) => res.json()) // <--- gives JSON from response
.catch((error: any)) => {
console.log(error);
console.log(error.json()); // <--- should give JSON from response, but gives ProgressEvent instead
return Observable.throw(error.json()); // also gives ProgressEvent when I 'subscribe' to the observable
})
.finally(() => {
this.loadingBarService.complete();
});
console.log(error)
输出Response
类型的错误; console.log(error.json())
输出ProgressEvent
类型的一些数据。
为什么我会获得ProgressEvent,而不是从非200状态代码响应发送的JSON?
这是ProgressEvent
:
{
bubbles: false,
cancelBubbles: false,
cancelable: false,
composed: false,
currentTarget: XMLHttpRequest,
defaultPrevented: false,
eventPhase: 0,
isTrusted: true,
lengthComputable: false,
loaded: 0,
path: Array(0),
returnValue: true,
srcElement: XMLHttpRequest,
target: XMLHttpRequest,
timeStamp: 1234.115,
total: 0,
type: "error",
__proto__: ProgressEvent
}
如您所见,ProgressEvent
不是我的回答。我的响应是一个JSON对象,只有一个error
属性,其中包含一条消息和一个状态。这是错的,为什么我没有得到我的答复?
答案 0 :(得分:1)
在基于Angular和Asp.Net Core的水疗项目中,我遇到了类似的问题。
如果是同一问题,则应该取决于客户端从服务器接收到的http响应中缺少CORS标头。 此响应违反了浏览器的CORS策略,很可能取决于服务器中未处理的运行时错误。
即使捕获所有错误并在返回的响应中放入一些信息和http状态,Angular在发生CORS约束违例时也不允许访问响应的任何信息,甚至http状态也无法访问,因此它会产生“空”响应:
Response {_body: ProgressEvent, status: 0, ok: false, statusText: "", headers: Headers, …} headers : Headers {_headers: Map(0), _normalizedNames: Map(0)} ok : false status : 0 statusText : "" type : 3 url : null..
我解决了这个问题,通过以下方式将CORS标头放入ASp.Net Core API服务器返回给客户端的响应中:
app.UseExceptionHandler(appError => {
appError.Run(async context => {
var _config = ServiceProviderFactory.ServiceProvider.GetService<AppConfigurations>();
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
context.Response.ContentType = "application/json";
context.Response.Headers.Add("Access-Control-Allow-Origin", $"{_config.AngularSiteUrl}");
context.Response.Headers.Add("Access-Control-Allow-Headers", "access-control-allow-origin,authorization,content-type");
var contextFeature = context.Features.Get<IExceptionHandlerFeature>();
if (contextFeature != null) {
var ex = contextFeature.Error;
var sp = services.BuildServiceProvider();
var _logger = sp.GetService<IGenericRepository<Log>>();
_logger.AddAndSave(new Log {
Description = "Exception not handled occurred",
Reason = ex.ToString(),
Type = "Error"
});
await context.Response.WriteAsync(
JsonConvert.SerializeObject(new {
Status = context.Response.StatusCode,
Message = "Internal Server Error."
}));
}
});
必须将代码放入Configure
类的Startup
方法中。
我希望这会有所帮助。