0

我很难弄清楚如何使用通过 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 标头并不容易,除此之外,我们还有测试人员正在侧向加载设备、运行代理等......

也就是说,尽管我能够找到与手头任务相关的文档,但这些示例都在 C# 中,而且我注意到并非 JavaScript 方面的所有内容都与该文档完全一致。

Stack Overflow 用户在这里提出了一个非常相似的问题,并且接受的解决方案是使用 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);
  })
);

总之,我不认为设置超时阈值这样简单的事情会如此痛苦,但我一直无法找到这样做的方法。

4

1 回答 1

1
  1. 根据使用 WinJS.xhr 或 HttpClient(HTML) 设置超时值

    使用 XMLHttpRequest 时,可以直接设置超时值,但使用 Windows.Web.Http.HttpClient 时不能这样做

    因此,当您使用 Windows.Web.Http.HttpClient 时,无法设置超时。

  2. 但后来我注意到传递给回调函数的参数(名为响应的参数)不是我所期望的.....问题是,我确实需要获取状态代码和失败原因,以便为我们的报告记录它(该代码未说明)

    那是因为您得到的不是 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);
        },
    );
    
于 2019-09-05T04:38:05.693 回答