首页 > 解决方案 > 如何在获取网络错误时获取 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

标签: javascriptfetch-api

解决方案


有时您发出请求并且响应无效,例如 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


推荐阅读