WinRT で利用できるようになった Windows.Web.HttpClient を使用して要求タイムアウトを設定する方法を理解するのが非常に困難です。私が取り組んでいるアプリケーションは、JavaScript タイプのユニバーサル Windows アプリです。「クライアント側」では、JavaScript は、C# でプログラミングする場合に通常使用するさまざまな名前空間を使用するためのアクセス権を持っています。これらの名前空間のメンバーは、次のようにウィンドウ オブジェクトからアクセスできます。
const {
HttpRequestMessage,
HttpMethod,
HttpClient,
} = R.pathOr({}, ['Windows', 'Web', 'Http'], window);
以下に投稿するコードの目的は、アプリが URL にリダイレクトする前に、簡単な到達可能性チェックを行うことです。JavaScript のより標準的な手段 (例: XMLHttpRequest) を使用して、なぜそうしなかったのか疑問に思う人がいる場合に備えて、 )、これは、CORS がこれらの要求に失敗する場合があるためです。私は大企業で働いているため、適切な access-control-allow-origin ヘッダーをどこにでも追加するように要求するのは簡単ではありません。また、デバイスにサイドロードしたり、プロキシを実行したりするテスターがいます...
とはいえ、当面のタスクに関連するドキュメントを見つけることはできましたが、例はすべて C# で書かれており、JavaScript 側のすべてがこのドキュメントと完全に一致しているわけではないことに気付きました。
スタック オーバーフロー ユーザーがここで非常によく似た質問をし、受け入れられた解決策は 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);
},
);
})
);
上記のコードはそれ自体でうまく機能するように見えましたが、コールバック関数に渡される引数 (response という名前の引数) が期待したものではないことに気付きました。少なくとも 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);
})
);
結論として、タイムアウトのしきい値を設定するような単純なことはそれほど苦痛だとは思いませんでしたが、そうする方法を見つけることができませんでした。