在 reactjs 应用程序中获取网络请求失败
Network request failed from fetch in reactjs app
我在 NodeJS 应用程序中使用 fetch
。从技术上讲,我有一个 ReactJS front-end 调用 NodeJS 后端(作为代理),然后代理调用不同域上的后端服务。
然而,从消费者的错误记录中(我自己无法重现这个问题)我发现很多这些代理调用(使用 fetch
)抛出一个错误,只是说 Network Request Failed
,这没有帮助。一些上下文:
- 这只发生在所有呼叫总数的一个子集上(比如说 5% 的流量)
- 遇到此错误的用户通常可以在一段时间后再次拨打相同的电话(下一对 minutes/hours/days),它将通过
- 从 Application Insights 中,我看不到浏览器、位置等之间的相关性
- 经常return快速调用,例如 < 100 毫秒
- 所有调用都是 HTTPS,非 HTTP
- 我们有一个来自
fetch-ponyfill
的 fetch polyfill,如果 fetch
不可用(Internet Explorer),它将接管。我确实测试了这个包本身,并且通话顺利进行。我还提到这个错误 确实 发生在支持 fetch
的浏览器上,所以我认为这不是错误。
- 获取所有请求的设置
- 方法是根据请求设置的,但我看到它在不同类型(GET、POST 等)上失败
- 模式设置为 'same-origin'。我认为这很奇怪,因为我们是从一个域向另一个域发送请求,但我尝试以不同的方式设置它,但它没有影响任何东西。另外,为什么有些请求对某些人有效,但对其他人无效?
- Body 根据发送的数据按请求设置。
- Headers 通常只是
Accept
和 Content-Type
,两者都设置为 JSON.
我之前曾尝试研究这个主题,但我发现的大多数帖子都引用了 React 本机应用程序 运行ning on iOS,您必须在 plist 文件中设置一些安全权限以允许 HTTP请求或与运输安全有关的事情。
我已经为 Application Insights 中的数据实现了特定点的日志记录,我可以看到调用了 fetch()
,但从未达到 then()
;它直接进入了 .catch()
。所以它甚至没有到达解析请求的代码,因为显然没有请求返回(然后我们解析 JSON 响应并调用其他函数,但就像我说的,它甚至没有达到这一点)。
这也很奇怪,因为请求永远不会返回,但它(经常)在 100 毫秒内失败。
我的怀疑:
- 一些消费者有某种 add-on 用于干扰请求的浏览器。虽然,我 运行 使用 uBlock Origin 和 HTTPS Everywhere,但我没有看到这个错误。我不确定还有什么修改请求会导致它立即失败。
- 调用通过,然后到达 Azure 应用程序网关,该网关可能由于某种原因(连接的客户端太多、端口不足等)而失败,并且 returns 立即使
fetch
在没有 运行 的情况下调用 .then()
响应。
对于 #2,我记得我跟踪了一个失败的网络调用并 returned Network Request Failed
:通过代理 -> 通过应用程序网关 -> 命中后端服务 -> 后端服务发送了响应。我目前正在请求访问后端服务日志,以便在最近的一些调用中验证这一点(上次我这样做是通过与后端开发人员的屏幕共享完成的),并希望清除返回客户端的路径( ReactJS 应用程序)。我确实记得它成功地进入了后端服务。
所以老实说,我不确定这里发生了什么。有没有人有任何见解?
根据您出色的描述和侦探工作,很明显问题出在您的 Node 应用程序和其他域之间。另一个域抛出错误,您的代理别无选择,只能说服务器上有错误。这就是为什么它总是抛出 500 系列错误,即您看到的 Network Request Failed
错误。
是间歇性问题,所以报错不一致。继续查看浏览器是在浪费您的时间,因为问题将在您的代理转换该请求或远程服务器上产生。您必须找到 那个 错误。
这是我要做的...
在 您的 Node 应用程序中实现 brute-force 登录。您可以使用 Bunyan, or 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 服务器上的日志将包含完整的请求和响应。从这里你可以找到共同点。和 () 问题的原因。
我在 NodeJS 应用程序中使用 fetch
。从技术上讲,我有一个 ReactJS front-end 调用 NodeJS 后端(作为代理),然后代理调用不同域上的后端服务。
然而,从消费者的错误记录中(我自己无法重现这个问题)我发现很多这些代理调用(使用 fetch
)抛出一个错误,只是说 Network Request Failed
,这没有帮助。一些上下文:
- 这只发生在所有呼叫总数的一个子集上(比如说 5% 的流量)
- 遇到此错误的用户通常可以在一段时间后再次拨打相同的电话(下一对 minutes/hours/days),它将通过
- 从 Application Insights 中,我看不到浏览器、位置等之间的相关性
- 经常return快速调用,例如 < 100 毫秒
- 所有调用都是 HTTPS,非 HTTP
- 我们有一个来自
fetch-ponyfill
的 fetch polyfill,如果fetch
不可用(Internet Explorer),它将接管。我确实测试了这个包本身,并且通话顺利进行。我还提到这个错误 确实 发生在支持fetch
的浏览器上,所以我认为这不是错误。 - 获取所有请求的设置
- 方法是根据请求设置的,但我看到它在不同类型(GET、POST 等)上失败
- 模式设置为 'same-origin'。我认为这很奇怪,因为我们是从一个域向另一个域发送请求,但我尝试以不同的方式设置它,但它没有影响任何东西。另外,为什么有些请求对某些人有效,但对其他人无效?
- Body 根据发送的数据按请求设置。
- Headers 通常只是
Accept
和Content-Type
,两者都设置为 JSON.
我之前曾尝试研究这个主题,但我发现的大多数帖子都引用了 React 本机应用程序 运行ning on iOS,您必须在 plist 文件中设置一些安全权限以允许 HTTP请求或与运输安全有关的事情。
我已经为 Application Insights 中的数据实现了特定点的日志记录,我可以看到调用了 fetch()
,但从未达到 then()
;它直接进入了 .catch()
。所以它甚至没有到达解析请求的代码,因为显然没有请求返回(然后我们解析 JSON 响应并调用其他函数,但就像我说的,它甚至没有达到这一点)。
这也很奇怪,因为请求永远不会返回,但它(经常)在 100 毫秒内失败。
我的怀疑:
- 一些消费者有某种 add-on 用于干扰请求的浏览器。虽然,我 运行 使用 uBlock Origin 和 HTTPS Everywhere,但我没有看到这个错误。我不确定还有什么修改请求会导致它立即失败。
- 调用通过,然后到达 Azure 应用程序网关,该网关可能由于某种原因(连接的客户端太多、端口不足等)而失败,并且 returns 立即使
fetch
在没有 运行 的情况下调用.then()
响应。
对于 #2,我记得我跟踪了一个失败的网络调用并 returned Network Request Failed
:通过代理 -> 通过应用程序网关 -> 命中后端服务 -> 后端服务发送了响应。我目前正在请求访问后端服务日志,以便在最近的一些调用中验证这一点(上次我这样做是通过与后端开发人员的屏幕共享完成的),并希望清除返回客户端的路径( ReactJS 应用程序)。我确实记得它成功地进入了后端服务。
所以老实说,我不确定这里发生了什么。有没有人有任何见解?
根据您出色的描述和侦探工作,很明显问题出在您的 Node 应用程序和其他域之间。另一个域抛出错误,您的代理别无选择,只能说服务器上有错误。这就是为什么它总是抛出 500 系列错误,即您看到的 Network Request Failed
错误。
是间歇性问题,所以报错不一致。继续查看浏览器是在浪费您的时间,因为问题将在您的代理转换该请求或远程服务器上产生。您必须找到 那个 错误。
这是我要做的...
在 您的 Node 应用程序中实现 brute-force 登录。您可以使用 Bunyan, or 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 服务器上的日志将包含完整的请求和响应。从这里你可以找到共同点。和 () 问题的原因。