javascript - 如何在获取网络错误时获取 url
问题描述
我需要向多个(最多 80 个)microHTTP 服务器发出 fetch 请求,其中一些可能没有运行。在这些情况下, fetch 会以网络错误响应。有没有办法将错误与原始 URL 相关联?
下面是 HTML 页面、Javascript 文件(我从中删除了大部分与业务相关的语句)和控制台消息。但首先,重申一下,我希望发现的是如何在“catch”块之外的某个地方捕获网络错误,或者如何访问包含 URL 的“catch”块中的某些结构。提前致谢。
HTML:
<!DOCTYPE HTML PUBLIC "//w3c//dtd html 4.01 Tradional//EN" "http://www.w3.org/TR/html4/loose/dtd">
<!-- Copyright Siemens AG 2018 -->
<!-- Main Web page for FCUD Overview Display. -->
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<title>Port Overview</title>
</head>
<body>
<!--- define the port table -->
<table id="porttable" border>
<thead>
<tr><th>Port</th>
<th>Last Update</th>
<th>data1</th>
<th>data2</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</body>
<script src="js/fetchExample.js"></script>
</html>
Javascript 文件 fetchExample.js:
const numberOfPorts = 5; // set to 5, but in production 80
const portIncrement = 50000;
var Host = "pickahost"; // the hostname of the server running the http servers
// MyPort class.
function MyPort (Json) { // MyPort Constructor
console.log("Creating Port object - " + Json.ObjectName);
this.ObjectName = Json.ObjectName;
this.fetchInProgress = false;
// there are many more properties, too.
// end of MyPort constructor
}; // end of MyPort class definition
function pollForUpdates (test) {
console.log('Starting polling pass ' + test + ": " + Date().toLocaleString() + " (" + Date.now() + ")");
var urlHost = "http://" + Host + ":"
for (port = 1; port <= numberOfPorts; port++) {
thisPort = ports[port];
console.log(" Polling " + thisPort.ObjectName + (thisPort.fetchInProgress
? " fetch in progress!"
: " now"));
if (! thisPort.fetchInProgress) {
// Check for identify updates.
var urlPort = urlHost + (port + portIncrement) + "/identify";
console.log(' requesting url=' + urlPort);
thisPort.fetchInProgress = true;
fetch(urlPort)
.then(function(response) {
console.log("Received response from GET of " + response.url);
var portOffset = response.url.indexOf(":5") + 1;
var portIndex = parseInt(response.url.slice(portOffset,portOffset+5)) - portIncrement;
ports[portIndex].fetchInProgress = false;
if (response.status == 200) {
// Examine the text in the response
response.json()
.then(function(data) {
console.log(" json results:", data.ObjectName);
var portIndex = parseInt(data.ObjectName.slice(4));
// save data from GET request ...
console.log(" stashed port (" + portIndex + ") - " + data.ObjectName + ": " + port[portIndex]);
} ).then (function() {displayDataRows(); return;} )
} // end of if {status == 200}
else {
response.json()
.then(function(data) {
console.log(" json results:", data.ObjectName);
var portIndex = parseInt(data.ObjectName.slice(4));
// save data from GET request ...
console.log(" stashed ports (" + portIndex + ") - " + data.ObjectName + ": " + ports[portIndex]);
} ).then (function() {displayDataRows(); return;} );
} // end of else {status != 200}
} ) // end of then call
.catch(function(err) {
console.log('Fetch Error :-S', err);
} )
} // end of if (! thisPort.fetchInProgress)
} // end of for port
// There is logic here to restart pollForUpdates after a delay, but the question relates to the fetch and catch
} // end of pollForUpdates
// Main program
console.log('starting PortStatus.js');
ports = new Array(numberOfPorts);
for (p=1; p<=numberOfPorts; ++p) {
var ObjName = "port" + ("0" + p).slice(-2);
ports[p] = new MyPort({ObjectName: ObjName});
}
testing = 0;
pollForUpdates(++testing);
console.log("pollForUpdates has returned to the main program.");
console.log('exiting fetchExample.js');
控制台输出:
starting PortStatus.js
fetchExample.js:69:1
Creating Port object - port01
fetchExample.js:8:5
Creating Port object - port02
fetchExample.js:8:5
Creating Port object - port03
fetchExample.js:8:5
Creating Port object - port04
fetchExample.js:8:5
Creating Port object - port05
fetchExample.js:8:5
Starting polling pass 1: Sat Jul 14 2018 22:58:11 GMT-0500 (CDT) (1531627091876)
fetchExample.js:17:5
Polling port01 now
fetchExample.js:22:9
requesting url=http://pickahost:50001/identify
fetchExample.js:28:13
Polling port02 now
fetchExample.js:22:9
requesting url=http://pickahost:50002/identify
fetchExample.js:28:13
Polling port03 now
fetchExample.js:22:9
requesting url=http://pickahost:50003/identify
fetchExample.js:28:13
Polling port04 now
fetchExample.js:22:9
requesting url=http://pickahost:50004/identify
fetchExample.js:28:13
Polling port05 now
fetchExample.js:22:9
requesting url=http://pickahost:50005/identify
fetchExample.js:28:13
pollForUpdates has returned to the main program.
fetchExample.js:79:1
exiting fetchExample.js
fetchExample.js:80:1
Fetch Error :-S
TypeError: NetworkError when attempting to fetch resource.
fetchExample.js:59:17
Fetch Error :-S
TypeError: NetworkError when attempting to fetch resource.
fetchExample.js:59:17
Fetch Error :-S
TypeError: NetworkError when attempting to fetch resource.
fetchExample.js:59:17
Fetch Error :-S
TypeError: NetworkError when attempting to fetch resource.
fetchExample.js:59:17
Fetch Error :-S
TypeError: NetworkError when attempting to fetch resource.
fetchExample.js:59:17
解决方案
有时您发出请求并且响应无效,例如 404 错误代码,在这种情况下会找到 url 作为响应,但有时您没有互联网或其他东西,您不会隐性响应,或者在这种情况下您会在很长一段时间后隐性地写一个用于从中获取和控制错误消息的包装器。
你应该这样做
fetch(url, options) {
let link=url;
let retries = 3;
let retryDelay = 1000;
let timeout = 4000;
if (options && options.retries) {
retries = options.retries;
}
if (options && options.timeout) {
timeout = options.timeout;
}
if (options && options.retryDelay) {
retryDelay = options.retryDelay;
}
let timeoutCallBack = new Promise((resolve, reject) => {
setTimeout(reject, timeout, 'request timeout');
});
return Promise
.race([timeoutCallBack, new Promise(function (resolve, reject) {
let wrappedFetch = function (n) {
fetch(url, options)
.then(function (response) {
if (response.ok)
resolve(response);
else throw error('bad error code' + link)
})
.catch(function (error) {
if (n > 0) {
setTimeout(function () {
wrappedFetch(--n);
}, retryDelay);
} else {
reject(error+link);//here you send change error massage
}
});
};
wrappedFetch(retries);
})]);
};
然后你可以导出这个模块并在你的js文件中简单地导入它就可以了。
PS:我使用自己的 write fetch ,当您没有收到任何响应时,您应该添加 timeout
推荐阅读
- excel - 更改活动工作表上的数据时,下工作表上的 VBA Excel 自动增量值
- java - 最大化 JFrame | 没有全屏
- google-cloud-platform - 在 GKE 气流中通过 KubernetesPodOperator 安装卷问题
- react-native - 如何在本机反应中将整个屏幕分成各种大小的部分
- wordpress - 允许“订阅者”上传媒体文件 - “抱歉,您不能将文件附加到此帖子。”
- postgresql - postgres_fdw 在分析期间减少数据下载
- matrix - 有没有办法将系数矩阵与 Julia JuMP 中的变量矩阵结合起来(两个数组的元素乘积)
- coq - 匹配一个道具?或任何其他定义“双重否定翻译”的方式
- python - 将一行的最后一个元素与 pandas 中一行的其余部分进行比较
- html - 双击以选择 contenteditable 元素中的文本,无法按预期工作