如何在请求未抵达后端时记录错误?(VueJS + .NET 6.0)
可行优化方案汇总
1. 后端前置中间件拦截文件类请求
在ASP.NET Core请求管道最前端添加自定义中间件,提前处理文件上传类请求,把原本在Web服务器层拦截的请求(如文件过大、损坏)拉到后端逻辑里处理,直接复用现有数据库日志机制。
示例代码:
public class FilePreCheckMiddleware { private readonly RequestDelegate _next; private readonly ILogger<FilePreCheckMiddleware> _logger; private readonly long _maxAllowedFileSize; // 从配置读取,比如10*1024*1024=10MB public FilePreCheckMiddleware(RequestDelegate next, ILogger<FilePreCheckMiddleware> logger, IConfiguration config) { _next = next; _logger = logger; _maxAllowedFileSize = config.GetValue<long>("AppSettings:MaxFileSize"); } public async Task InvokeAsync(HttpContext context) { // 仅处理文件上传请求 if (context.Request.ContentType?.StartsWith("multipart/form-data") == true) { // 检查请求大小 if (context.Request.ContentLength.HasValue && context.Request.ContentLength > _maxAllowedFileSize) { context.Response.StatusCode = StatusCodes.Status413PayloadTooLarge; await context.Response.WriteAsJsonAsync(new { Message = "文件大小超出限制" }); // 用现有日志服务记录 _logger.LogError("请求未抵达业务逻辑层:文件大小超出限制,客户端IP:{Ip}", context.Connection.RemoteIpAddress); return; } // 检测文件是否损坏(可选) try { context.Request.EnableBuffering(); // 保留请求流供后续中间件使用 await context.Request.Body.CopyToAsync(Stream.Null); // 尝试读取流验证完整性 context.Request.Body.Position = 0; } catch (IOException ex) { context.Response.StatusCode = StatusCodes.Status400BadRequest; await context.Response.WriteAsJsonAsync(new { Message = "文件损坏或格式错误" }); _logger.LogError(ex, "请求未抵达业务逻辑层:文件损坏,客户端IP:{Ip}", context.Connection.RemoteIpAddress); return; } } await _next(context); } } // 注册中间件(Program.cs) app.UseMiddleware<FilePreCheckMiddleware>();
2. 利用Web服务器层捕获未抵达后端的请求
如果是Web服务器(IIS/Nginx)直接拦截了请求(比如IIS默认的413错误),可以配置服务器日志记录这类异常,再通过日志工具同步到数据库:
- IIS:开启「失败请求跟踪规则」,跟踪状态码为413、400等未到达ASP.NET Core的请求,生成的日志文件可通过Serilog/NLog等工具解析后入库。
- Nginx:在配置文件中指定
error_log记录4xx/5xx级别的错误,同时在server块中添加对大文件请求的日志标记,再用Filebeat等工具将日志同步到数据库或统一日志系统。
3. 前端缓存延迟上报(替代即时请求)
避免前端单独发日志请求可能再次失败的问题,改为将未抵达后端的请求日志暂存前端本地,在后续正常请求时附带上报:
Vue + Axios示例:
// Axios响应拦截器 axios.interceptors.response.use( response => response, error => { // 判断请求未抵达后端的场景:无响应对象、413、请求被中断等 if (!error.response || [413, 0].includes(error.response?.status)) { const errorLog = { logType: "unreachable_backend", requestUrl: error.config.url, requestTime: new Date().toISOString(), clientInfo: navigator.userAgent, errorMsg: error.message || "请求未抵达后端" }; // 本地缓存最多保留10条日志 const storedLogs = JSON.parse(localStorage.getItem("pendingErrorLogs")) || []; storedLogs.push(errorLog); localStorage.setItem("pendingErrorLogs", JSON.stringify(storedLogs.slice(-10))); } return Promise.reject(error); } ); // 在任意正常请求(如页面初始化、表单提交)时附带上报 async function reportPendingLogs() { const storedLogs = JSON.parse(localStorage.getItem("pendingErrorLogs")) || []; if (storedLogs.length === 0) return; try { await axios.post("/api/logs/report-pending", { logs: storedLogs }); localStorage.removeItem("pendingErrorLogs"); } catch (e) { // 上报失败则保留日志,下次重试 } } // 页面加载时调用 reportPendingLogs();
4. 统一日志收集系统
引入ELK(Elasticsearch+Logstash+Kibana)或Grafana Loki这类工具,将Web服务器日志、后端应用日志、前端日志统一收集存储,无需单独入库,通过日志系统即可查询所有异常场景,包括请求未抵达后端的情况。
内容的提问来源于stack exchange,提问作者Luis Angel Urena Lopez
相关产品推荐
相关产品推荐

