【发布时间】:2020-11-11 12:09:34
【问题描述】:
作为序言,我正在为 Syncthing 开发 pull request - 一个连续文件同步软件。拉取请求将允许从 GUI 看到所有连接的远程计算机的 url。
我遇到的问题是远程机器的 OPTIONS 请求失败。在程序显示远程机器的 url 之前,维护人员要求 GUI 验证机器将允许用户访问远程机器 GUI(如果机器设置了身份验证,GET 请求将失败,因此验证 OPTIONS 响应是够好了)。我可以验证 CORS 是否已设置 properly。我什至可以发送 curl 请求并通过浏览器转到远程计算机,但无论出于何种原因,javascript OPTIONS 请求都会收到网络错误。当我查看将响应请求的远程机器时,无论是 curl、javascript 还是浏览器,它都会返回一个 201 请求。但是,当我查看发送请求的机器的 chrome 网络控制台时,我看到选项请求失败,但后来,似乎请求成功了。我的直觉是机器发送有效响应并重试之前的请求超时。尽管如此,在设置更长的选项请求标头后,它不会改变结果,就好像超时持续时间不会影响错误一样。
这个 javascript sn-p 来自使用 angular 的 GUI。它使用角度 $http 库。
$scope.probeAddress = async function (address, successCallBack) {
try {
var response = await $http({
method: "OPTIONS",
url: address,
timeout: 40000,
});
return response.$$state.status >= 200 && response.$$state.status < 300;
} catch (error) {
console.log(error);
}
}
它以网络错误响应,response.$$state = 0。
chrome 网络控制台的图片。我认为它目前是按持续时间排序的。如果按接收顺序排序,红色错误将排在第一位。我不知道为什么要重试OPTIONS请求,但是我绝对没有编写重试代码。两个 IP 地址都有身份验证设置。
其中一台机器接收请求的日志。如您所见,两个 OPTIONS 请求都收到 204 响应。它说响应是在 0.02 毫秒内发送的,而浏览器只等待 112 毫秒
【问题讨论】:
-
OPTIONS 请求通常由浏览器在访问跨源资源时自动完成 - 您不需要自己发出该请求(即使您这样做也无助于 CORS)
-
另外,
$http是异步的,您需要使用它返回的承诺。您无法像现在尝试那样制作return,因为您在请求完成之前返回。见How do I return the response from an asynchronous call? -
@charlietfl 我用异步等待更改了代码。我仍然看到网络错误。我的菜鸟错误。
-
好的,但如上所述,您永远不需要执行自己的 OPTIONS 请求。阅读 CORS 的工作原理(研究基础知识的简单主题)
-
@charlietfl 我熟悉 CORS。我不必做一个 GET 因为请求之前发送一个预检选项。尽管如此,如前所述,GET 请求在这里没有意义,因为由于某些 GUI 要求用户提交用户名和密码,因此不可能成功。尽管失败的 GET 请求会告诉机器是否允许用户访问它并最终进行身份验证,但最好不要编写会产生错误的代码(因此未来的开发人员不会认为存在错误)。一个 OPTIONS 请求给了我我需要的东西,而无需身份验证或导致错误。
标签: javascript http networking