【问题标题】:How to catch Chrome error net::ERR_FILE_NOT_FOUND in XMLHttpRequest?如何在 XMLHttpRequest 中捕获 Chrome 错误 net::ERR_FILE_NOT_FOUND?
【发布时间】:2018-06-16 01:58:51
【问题描述】:

我想创建能够读取本地文件并使用其中编写的代码的 chrome 扩展程序。我的简单代码是:

const readFile = (filePath) => {
  return new Promise(function (resolve, reject) {
    const xhr = new XMLHttpRequest()
    xhr.onerror = (error) => {
      reject(error)
    }
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        resolve(xhr.response)
      }
    }
    xhr.ontimeout = function () {
      reject('timeout')
    }
    xhr.open('GET', filePath)
    xhr.send()
  })
}

async function () {
    const code = await readFile(jsFilePath)
    console.log(code)
}

当我的文件路径正确时,此代码成功运行。但是当它不是 Chrome 控制台时会抛出这个错误:

GET file:///home/maxim/Documents/test.jsa net::ERR_FILE_NOT_FOUND

通常的 try/catch 块不起作用

async function () {
  try {
    const code = await readFile(jsFilePath)
    console.log(code)
  } catch (e) {
    console.log(e)
  }
}

我怎样才能捕捉到这种类型的错误?

【问题讨论】:

  • 使用xhr.onloadend = e => e.type !== 'error' ? resolve(xhr.response) : reject(e) 监听器代替onerroronreadystatechange
  • 不幸的是,这对我的情况没有帮助。 e.type 返回 'loadend' 并且 chrome 抛出 net::ERR_FILE_NOT_FOUND。
  • 在 try 和 catch 中添加另一个 console.log 并查看实际打印的是哪个

标签: javascript google-chrome google-chrome-extension


【解决方案1】:

首先net::ERR_FILE_NOT_FOUND是一个浏览器错误(见Chromium/Chrome error listChrome fail error codes,所以你不能用JS代码捕获它。

特别是net::ERR_FILE_NOT_FOUND“不表示致命错误。通常此错误将作为通知生成”。

因此,最好的方法是将 onloadend 处理程序附加到 XMLHttpRequest,在 Ajax 请求完成时触发(成功或失败)。

但是你不能检查状态,实际上statusstatusTextreadyState属性的值在文件存在的情况下和文件的情况下XMLHttpRequest找不到总是:

status: 0
statusText: ""
readyState: 4

反之,当文件未找到或其他情况时,您可以检查属性responseresponseTextresponseURL,其值为“”:

response: <file content>
responseText: <file content>
responseURL: "file:///..."

要检查的其他值是 event (ProgressEvent) loaded 属性,如果找不到文件(或在其他情况下加载的字节),该属性的值为 0。

所以代码可能是:

const readFile = (filePath) => {
    return new Promise(function (resolve, reject) {
        const xhr = new XMLHttpRequest()
        xhr.onloadend = (event) => {
            console.log("xhr.onloadend", event, xhr.status, xhr.statusText, xhr.readyState, xhr);
            if (event.loaded && xhr.response) {
                resolve(xhr.response);
            } else {
                reject("error");
            }
        }
        xhr.open('GET', filePath);
        xhr.send();
    });
}

【讨论】:

  • 非常感谢!我认为这对于我的情况来说是一个可以接受的解决方案)我发现使用async === false 也可能会有所帮助,因为在这种情况下,send 方法会引发一个错误,该错误可以在 try/catch 块中捕获。但我认为,关于同步请求的 Chrome 弃用通知会使您的解决方案更好。
  • 而且我发现使用xhr.responseURL而不是xhr.response更好。如果我们的文件为空,那么 xhr.response 也将为空,Promise 将拒绝错误。
  • 是的,这是真的,如果文件存在但它是空的 xhr.responseURL 无论如何都包含一个字符串(url/路径)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-28
  • 2013-04-02
  • 2020-02-01
  • 1970-01-01
  • 2011-06-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多