无法在 JavaScript 中为 Windows.Web.Http.HttpClient 添加超时
Posted
技术标签:
【中文标题】无法在 JavaScript 中为 Windows.Web.Http.HttpClient 添加超时【英文标题】:Cannot add timeout for Windows.Web.Http.HttpClient in JavaScript 【发布时间】:2020-01-01 03:22:22 【问题描述】:我很难弄清楚如何使用通过 WinRT 提供的 Windows.Web.HttpClient 设置请求超时。我正在开发的应用程序是一个 javascript 类型的通用 Windows 应用程序。 “客户端”,JavaScript 可以访问使用在 C# 中编程时通常会使用的各种命名空间。这些命名空间的成员可以像这样从 window 对象访问:
const
HttpRequestMessage,
HttpMethod,
HttpClient,
= R.pathOr(, ['Windows', 'Web', 'Http'], window);
我将在下面发布的代码的目标是在应用重定向到 URL 之前对 URL 进行简单的可访问性检查,以防有人想知道为什么我没有使用 JavaScript 中更标准的方法(例如:XMLHttpRequest),这是因为 CORS 有时会失败这些请求。由于我在一家大公司工作,因此要求在任何地方添加适当的 access-control-allow-origin 标头并不容易,除此之外,我们还有测试人员正在侧向加载设备、运行代理等......
也就是说,虽然我能够找到与手头任务相关的documentation,但这些示例都是用 C# 编写的,而且我注意到并非 JavaScript 方面的所有内容都与本文档完全一致。
Stack Overflow 用户提出了一个非常相似的问题here,并且接受的解决方案是使用 CancellationTokenSource。然而,据我所知,这个问题的 C# 解决方案不适用于 JavaScript 方面,但我确实想出了一个接近解决方案,我可以使用 setTimeout 取消任务。请注意,为了便于阅读,我在此处编辑了一些代码行。
const isReachable = async (url) => (
new Promise((resolve) =>
const message = new HttpRequestMessage();
message.method = new HttpMethod('HEAD');
message.requestUri = new Uri(url);
const client = new HttpClient();
const task = client.sendRequestAsync(message);
const timeout = setTimeout(() => task.cancel(), 5000);
task.done(
(result) => // Success
clearTimeout(timeout);
resolve(true);
,
(result) => // Failure
clearTimeout(timeout);
resolve(false);
,
);
)
);
上面的代码本身似乎运行良好,但后来我注意到传递给回调函数(名为响应的arg)的参数不是我所期望的。我期望至少类似于 XHR 响应,但我得到的似乎是任务的成功或错误响应。问题是,我确实需要获取状态代码和失败原因,以便为我们的报告记录(该代码未显示)。
这是我的下一次(部分)尝试,显然,如果我等待响应,那么我实际上确实得到了一个与 XHR 响应足够相似的对象以用于该目的。但是,由于我在这里等待任务,所以我没有将它存储在变量中,以便在我超时后可以取消它。
const urlIsReachable = async (url = '') => (
new Promise(async (resolve) =>
const request = new HttpRequestMessage();
request.method = new HttpMethod('HEAD');
request.requestUri = new Uri(url);
const client = new HttpClient();
const response = await client.sendRequestAsync(request);
const statusCode: status = response;
if (status === 200)
resolve(true);
return;
resolve(false);
)
);
总之,我不认为设置超时阈值这样简单的事情会如此痛苦,但我一直找不到这样做的方法。
【问题讨论】:
【参考方案1】:根据Setting timeout values with WinJS.xhr or HttpClient(html):
使用 XMLHttpRequest 时可以直接设置超时值,但使用 Windows.Web.Http.HttpClient 时不能这样做
因此在使用 Windows.Web.Http.HttpClient 时无法设置超时。
但后来我注意到传递给回调函数的参数(名为响应的参数)不是我所期望的.....问题是,我确实需要获取状态代码和失败原因以便记录它用于我们的报告(代码未显示)
这是因为您得到的不是 xhr 响应,而是 WinRT Windows.Web.Http.HttpResponseMessage 对象,您可以使用 result.asyncOpType 来查看。如果您想获取错误消息,只需在 onError 回调中使用 result.message:
task.done(
(result) => // Success
clearTimeout(timeout);
resolve(true);
,
(result) => // Failure
let msg=result.message;//message is 'Canceled' if timeout callback's called
clearTimeout(timeout);
resolve(false);
,
);
【讨论】:
以上是关于无法在 JavaScript 中为 Windows.Web.Http.HttpClient 添加超时的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 Cocos2D-X 在 Windows 的 plist 中为 png 充气