【问题标题】:Error handling in Dynamic JS loading动态 JS 加载中的错误处理
【发布时间】:2009-11-05 11:06:53
【问题描述】:

我正在加载一个 JS 文件,该文件仅适用于我的网页的一部分,仅当用户导航到页面上的该选项卡时。​​p>

var scriptFile = document.createElement("script");
scriptFile.setAttribute("type", "text/javascript");
scriptFile.setAttribute("src", scriptURL);

我正在尝试为此动态加载提出一种错误处理机制,以便在 JS 加载超时或 JS 在 URL 指定的位置不可用时显示错误消息。

这就是我尝试实现错误处理的方式(对于 IE):

scriptFile.onreadystatechange = function() { // For IE
    if (this.readyState == 'complete' || this.readyState == 'loaded') {
        // Display content in tab
    } else {
        // Display error message
    }
}

这导致了一个问题。当一切正常并且 JS 按预期存在时,我会先收到错误消息,然后才是正确的内容。

经过一番头脑风暴,我发现readyState是先从“未初始化”变为“正在加载”,然后再变为“已加载”。当状态为“正在加载”时,显示错误消息。之后,状态变为“已加载”,此时正在显示内容。

任何想法如何处理这个问题,以便最初不显示错误?

【问题讨论】:

  • 更新:即使给定的 URL 中没有 JS,我也需要显示错误消息。即使 JS 出现 404 错误,状态也会变为“完成”,并且页面正在尝试显示数据.. 显示 JS 错误。我该如何处理?

标签: javascript error-handling dynamic-loading


【解决方案1】:

因为没有“哎呀我死了!”状态,不能显示错误信息。

编辑:删除了代码,因为我的意思是你不能这样做。使用 AJAX 请求,您可以检查响应并查看它是否为 404,但您不能使用脚本标记来执行此操作。

edit2:再想一想,为什么不通过 AJAX 获取脚本并在 document.body 中注入一个 ''? p>

要检查 AJAX 请求是否已被轰炸,请检查 XMLHTTPRequest 对象的状态属性。如果是 404,那就是 404。

另外,您不应该手工做这些事情。我总是建议使用 Prototype 或 jQuery。由于我已经被 Prototype 宠坏了,我不应该试图解释如何检查请求的状态。为什么不在这里问另一个问题如何处理 AJAX 请求?专业人士肯定会告诉你如何处理各种故障,而不仅仅是 404。

【讨论】:

  • 呵呵.. 我练习的重点是显示错误消息。 :)
  • 我知道,但你无法判断脚本是否失败。至少我的版本在对象第一次改变状态后不会放弃。
  • 请检查我的更新。我需要处理 JS 根本没有加载的情况(HTTP 404)。
  • 好的,所以我使用 AJAX 调用加载 JS 的内容并将其加载到文档正文中,对吧?值得一试。很抱歉成为 AJAX 菜鸟,但是如果状态为 404,您如何检查那里?
  • 您检查响应标头。让我搜索一些您可以使用的文档。
【解决方案2】:

如果有一个(全局)变量来检查它是否已加载(例如,脚本将在加载完成后设置它)然后用计时器设置另一个函数(已经在加载函数之前的页面上)来检查该变量如何? (例如 5 秒延迟?)

如果未设置变量(在预定义的时间后),向用户显示错误。

【讨论】:

  • 但这意味着您只允许 5 秒加载脚本;一旦他们通过了,如果它仍然存在,您仍然会显示错误消息。如果用户的调制解调器由于重度色情内容的大量流式传输或对笑猫的大量请求而负载过重怎么办?
  • 你可以做到 10,无论如何 :-)
  • 笑笑猫可能很重,你知道的。他们吃了很多芝士汉堡。说真的,我不同意。我认为固定超时是错误的。
  • 我理解你的担心,但正如你上面所说,没有其他解决方案,所以这只是一种解决方法。
【解决方案3】:

我认为你需要废弃“else”,因为它总是会经历“加载”状态,无论它是否可以工作,所以“else”分支没有做任何有用的事情。

改为设置超时。

var scriptTimer = setTimeout(function() {
  // show error message
  // (should ideally precede with a check the content hasn't
  // been displayed, in case of race condition)
});
scriptFile.onreadystatechange = function() { // For IE
    if (this.readyState == 'complete' || this.readyState == 'loaded') {
       clearTimeout(scriptTimer);
       // now display content in tab
    }
}

【讨论】:

  • 即使在超时之后,脚本也没​​有加载会发生什么?我该如何处理?
  • 您已显示错误消息;没有其他事情需要处理。如果您愿意,您可以再试几次,即从计数器“var scriptAttempts = 3”开始,然后尝试从 setTimeout 处理程序再次加载脚本。每次您运行该函数来加载脚本时,它都会检查 scriptAttempts > 0,并递减 scriptAttempts,直到放弃并显示错误消息。如果您正在执行所有这些操作,我还会显示进度指示器,因为延迟可能会很长。
【解决方案4】:

编辑:我的方法是错误的 - 按照 Kaze 的建议使用 AJAX

【讨论】:

  • 如果不是“完成”或“加载”,怎么可能不是“加载”?
  • 由于他在 else 部分显示错误消息,我认为他正在寻找一些“错误”状态 - 谷歌搜索并发现它不是那样工作的。我想通过 AJAX 加载并检查 404 是可行的方法。
猜你喜欢
  • 1970-01-01
  • 2016-09-26
  • 1970-01-01
  • 2019-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-13
相关资源
最近更新 更多