我在 NodeJS 应用程序中使用 fetch
。从技术上讲,我有一个 ReactJS 前端调用 NodeJS 后端(作为代理),然后代理调用不同域上的后端服务。
但是,从消费者的日志记录错误(我自己无法重现此问题)中,我发现许多代理调用(使用 fetch
)会抛出一个错误,该错误仅显示 网络请求失败
,这没有任何帮助。一些背景:
- 这只发生在所有调用总数的一部分(假设流量的 5%)
- 遇到此错误的用户通常会在一段时间后(接下来的几分钟/几小时/几天)再次进行相同的调用,并且该错误将会通过
- 从 Application Insights 中,我发现浏览器、位置等之间没有关联
- 调用通常返回速度很快,例如 < 100 毫秒
- 所有调用均为 HTTPS,非 HTTP
- 我们有一个来自
fetch-ponyfill
的 fetch polyfill,如果fetch
不可用(Internet Explorer),它将接管。我确实测试了这个包本身,并且调用进行得很好。我还提到,这个错误确实发生在支持fetch
的浏览器上,所以我认为这不是错误。 - 获取所有请求的设置
- 方法是根据请求设置的,但我发现它在不同类型(GET、POST 等)上失败
- 模式设置为“同源”。我认为这很奇怪,因为我们从一个域向另一个域发送请求,但我尝试以不同的方式设置它,但它没有影响任何内容。另外,为什么有些请求对某些请求有效,但对其他请求无效?
- 正文是根据发送的数据按请求设置的。
- header 通常只是
Accept
和Content-Type
,均设置为 JSON。
我之前曾尝试研究过这个主题,但我发现大多数帖子都引用了在 iOS 上运行的 React native 应用程序,您必须在 plist 文件中设置一些安全权限以允许 HTTP 请求或与传输安全相关的操作。
我已经在 Application Insights 中实现了数据记录特定点,并且我可以看到调用了 fetch()
,但从未到达 then()
;它直接进入.catch()
。所以它甚至没有到达解析请求的代码,因为显然没有请求返回(然后我们解析 JSON 响应并调用其他函数,但就像我说的,它甚至没有到达这一点)。
这也很奇怪,因为请求永远不会返回,但它(通常)在 100 毫秒内失败。
我的怀疑:
- 一些消费者的浏览器有某种附加组件,会干扰请求。虽然,我使用 uBlock Origin 和 HTTPS Everywhere 运行,但没有看到此错误。我不确定还有什么可能会修改请求,从而导致它立即失败。
- 调用完成,然后到达 Azure 应用程序网关,该网关可能会因某种原因(连接的客户端过多、端口不足等)而失败,并返回一个响应,该响应会立即导致
获取
失败调用而不在响应上运行.then()
。
对于#2,我记得我跟踪了一个失败的网络调用并返回网络请求失败
:通过代理实现 -> 通过应用程序网关实现 -> 访问后端服务 -> 后端服务发送了响应。我目前正在请求访问后端服务日志,以便在最近的一些调用中验证这一点(上次我这样做是通过与后端开发人员的屏幕共享来完成的),并希望清除返回客户端的路径( ReactJS 应用程序)。我确实记得它成功地到达了后端服务。
所以老实说我不确定这里发生了什么。有没有人有任何见解?
最佳答案
根据您出色的描述和侦探工作,很明显问题出在您的 Node 应用程序和其他域之间。另一个域抛出错误,您的代理别无选择,只能说服务器上有错误。这就是为什么它总是抛出 500 系列错误,即您看到的网络请求失败
错误。
这是一个间歇性问题,因此错误不一致。继续查看浏览器是浪费时间,因为问题将在翻译该请求的代理中或在远程服务器上产生。您必须找到那个错误。
这就是我要做的...
在您的 Node 应用程序中实现暴力日志记录。您可以使用Bunyan ,或Winston或者只是 require(fs)
并在发生错误时写入某个文件。然后看看结果。仅当来自其他服务器的响应代码在 400 或 500 范围内时才将其注销。记录请求对象和响应对象。
Bunyan 是这样的:
fetch(urlToRemoteServer)
.then(res => res.json())
.then(res => whateverElseYoureDoing(res))
.catch(err => {
// Get the request & response to the remote server
log.info({request: req, response: res, err: err});
});
本例中的 res 是我们刚刚从其他域获得的响应,req 是我们对他们的请求。
Azure 服务器上的日志将包含完整的请求和响应。从中你可以发现共性。以及 (🤞) 问题的原因。
关于reactjs - 在reactjs应用程序中获取网络请求失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70791538/