W3C DOM异常对象DOMException介绍

这篇文章发布于 2012年05月14日,星期一,20:00,归类于 JS相关。 阅读 225705 次, 今日 2 次 33 条评论

 

最近用jqmobi折腾个小项目,由于框架本身一起其他使用原因,连续遇到DOMException 12以及DOMException 7错误。查阅各个资料,发现国内几乎没有相关比较系统的文章。为方便他人以及自己查找匹对,故这里整理一篇小文。

本文内容整理参考自:SitePoint > Reference > JAVASCRIPT > DOM Core > DOMException

一、DOMException是?

DOMException是W3C DOM核心对象。DOMException接口表示一个处理的错误,当一个操作不可能执行的时候,会抛出一个异常。例如试图创建一个无效的DOM, 或通过一个不存在的节点作为参数节点操作方法。

举个板栗,如下代码:
var node = document.getElementsByTagName('h1').item(0);
var refnode = node.nextSibling;
var newnode = document.createTextNode('这就是为何你挂了!');
node.insertBefore(newnode, refnode);

上面代码演示了一个会嗝屁的insertBefore操作,因为refnode不是一个子节点。在Opera浏览器下,上面的操作就会导致下面显示的异常错误:

Inline script thread
Error:
Unhandled Exception: [Object DOMException]
code: 8
message: NOT_FOUND_ERR

DOM并不对每个可能发生的错误定义一个异常,例如参数、语法错误就不在其中,这种情况有其自己的一套错误报告机制来处理。

实际上,大多数浏览器已经把DOM异常作为本地机制。除了显示异常代码和信息外,还显示了浏览器可以提供的其他信息(如行数或堆栈轨迹)

二、DOM Exceptions兼容性

兼容性见下表:

Internet Explorer Firefox Safari Opera
5.5 6.0 7.0 1.5 2.0 3.0 1.3 2.0 3.0 9.0 9.5

上表的兼容性数据还是比较老的,按照常规,IE9也应该支持的,最新的Chrome浏览器一定支持。

考古价值的IE浏览器不支持该接口,他们使用本地错误(解析错误之类)。例如,上面插入节点的例子,在老IE下抛出的就是:Invalid argument. 在XML中,会给出更多的信息:Insert position Node must be a Child of the Node to insert under.

三、常量列表

该接口定义了ExceptionCode整数值——向外暴露code属性——指向每种类型的错误;这些定义参考下面些常量:

INDEX_SIZE_ERR code 1
如果索引是负值,或是超过了允许值。例如splitText的offset参数比字符串长度还要长。
DOMSTRING_SIZE_ERR code 2
DOMString的特定字符数据太大。其大小显示是依赖实现的,未被DOM定义(每个浏览器的限制细节参见DOM Core)。
HIERARCHY_REQUEST_ERR code 3
节点不允许有新的子节点,或者新节点已经是其该节点的祖先节点。例如,尝试将Element节点塞入Text节点。
WRONG_DOCUMENT_ERR code 4
试图使用跨文档的节点操作。例如,appendChild的子节点来自其他文档。而不是先输出(使用importNode)。
INVALID_CHARACTER_ERR code 5
一个非法的或无效的字符指定一个有限制的字符串,例如元素的name.
NO_DATA_ALLOWED_ERR code 6
为不支持数据的节点指定数据。如Element节点本身不包含数据,其子节点包含。
NO_MODIFICATION_ALLOWED_ERR code 7
试图修改一个不能被修改的节点。例如,装载一个只读的节点。
NOT_FOUND_ERR code 8
引用的节点不存在。例如,insertBefore相关子节点不是引用的子节点。
NOT_SUPPORTED_ERR code 9
实现不支持的特定操作。例如使用一个节点的方法,但是此方法并没有实现,就是抛出此错误。
INUSE_ATTRIBUTE_ERR code 10
试图添加一个正在使用的属性。例如使用setAttributeNode引用一个已经在另一个元素使用的Attr, 而不是克隆它首先(使用cloneNode)。
INVALID_STATE_ERR code 11
试图使用一个不可用的对象。这种错误的抛出通常是因为某些内部原因,方法无法实现特定的操作。
SYNTAX_ERR code 12
无效或非法的字符串被指定。例如,用无效的CSS值设置selectorText属性的CSSStyleRule. //zxx: 我遇到该错误是因为在特定情况下,对<title>标签使用了innerHTML方法。
INVALID_MODIFICATION_ERR code 13
尝试修改一个节点的类型。例如,使用不匹配最初规则类型的值设置cssText属性的CSSRule.(如,为at-rule设置style-rule values值).
NAMESPACE_ERR code 14
操作与命名空间冲突。例如createElementNS使用的名称歪瓜裂枣。
INVALID_ACCESS_ERR code 15
一个属性或操作不支持指定的节点。例如,尝试在一个不含float值的CSS属性上使用getFloatValueCSSPrimitiveValue方法。

关于code:ExceptionCode(也就是上面列表中一而再再而三的code)的整数值表示DOMException的类型。

四、最后的说明

本文内容没什么看头。重要的记住这里有篇关于DOMException的文章即可,回头可以迅速找到就OK啦!上面展示的列表中对ExceptionCode不同值的解释太泛太笼统了,后面的举例感觉是要故意展示一些方法,属性等。因此,离自己所希望的人人进来,人人都有启发的愿景还是有一定差距的。DOMException的各个错误也是不容易碰到的,但是,一旦碰到是很头疼的,整个页面的JS基本上就会报废,而且,错误不易查找。例如,使用数字作为元素id,在某些特定情况下,某些浏览器下,就会报DOMException的错误。

我现在比以前懒的,要是过去,刚毕业那会,激情无限的时候,估计会废寝忘食把每个错误都呈现一遍。现在嘛,唉,搞不动了,而且,错误呈现实在不易。因此,抱歉,大家只能将就上面一些笼统泛泛的解释了吧。

不过嘛,团结才是力量,本文可以无限评论的。因此,您要是遇到DOMException错误,并因为这里或那里解决了,记得一定要把您遇到的错误code、具体情境以及解决方法。以评论或邮件(zhangxinxu@zhangxinxu.com)的形式告知,我一定会整理出现,放在正文中的。这样,集思广益,细流成海,以后,一旦遇到浏览器报DOMException的错误,来这里就可以搞定,岂不很好。

因此,希望本文可以成为一个解决DOMException错误的一个平台,收集各个同行的经验,造福自己以及其他同行;而不仅仅是个普通文章。想法是美好的,具体就要看您的贡献与支持了!一起努力吧!

(本篇完)

分享到:


发表评论(目前33 条评论)

  1. ZhangSy说道:

    我遇到的是iOS9系统中,post接口报错:SyntaxError: DOM Exception 12,
    查了DOM文档一直在找css方面的原因,
    后来才发现是给Content-Type赋值的时候,前面多打了一个空格

  2. 八月说道:

    如果code是18呢

  3. 丢丢说道:

    react项目遇到这个情况

    • 丢丢说道:

      Uncaught DOMException: Failed to execute ‘createElement’ on ‘Document’: The tag name provided

  4. 无畏说道:

    使用数字id报错chrome

  5. lalala说道:

    一个页面镶嵌了一个跨域的iframe,window.frames[0]可以取到,但是取其中的值时,Uncaught [object DOMException]。
    具体原因不明,有见过的么。。

    • lalala说道:

      Uncaught DOMException: Blocked a frame with origin “http://localhost” from accessing a cross-origin frame.
      at Error (native)
      at :2:17
      at Object.InjectedScript._evaluateOn (:875:140)
      at Object.InjectedScript._evaluateAndWrap (:808:34)
      at Object.InjectedScript.evaluate (:664:21)

  6. 扎西说道:

    有一个iframe的内容是会改变的,需要在打开页面的时候获得iframe的内容高度来设置iframe的高度,我是等iframe onload的时这样$(“#comment”).contents().find(“body”).height()获取高度的。有时候会报错,报错如下,请问这是什么原因,有什么解决方案?在此先感谢

    Uncaught DOMException: Failed to read the ‘contentDocument’ property from ‘HTMLIFrameElement’: Blocked a frame with origin “http://qy.iwgame.com” from accessing a cross-origin frame.

  7. Nocti说道:

    微信web开发者工具 偶尔会出现这个问题
    undefined:1 Uncaught (in promise) DOMException: Failed to load because no supported source was found.
    问题复现方法:直接使用 .play 方法播放不支持的格式的音频
    一些浏览器容器在 load 完成之前使用 play 方法播放就会报这个错
    (一般都是因为load的音频格式不支持)
    目前没有解决方案 电脑的开发者工具上失败之后在手机上通常不会出错 出错的时候重启微信/手机即可 就是客服妹子要麻烦点了

  8. 张浅说道:

    HTML5 new Worker(URL)的时候,出错了:VM580:2 Uncaught DOMException: Failed to construct ‘Worker’: Script at cannot be accessed from origin ‘null’.
    at Error (native)
    at :2:1
    at Object.InjectedScript._evaluateOn (:878:140)
    at Object.InjectedScript._evaluateAndWrap (:811:34)
    at Object.InjectedScript.evaluate (:667:21)
    为什么要这样

  9. 贡献一枚说道:

    Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause().
    通过new Audio(file)的方式加载音效,一个音效在播放,突然play别的音效,就会报这个错。表示很无赖,查这个http://stackoverflow.com/questions/37136077/how-do-i-prevent-the-error-uncaught-in-promise-domexception-the-play-reque也解决不了,鑫大能否指点指点?

    • alpha说道:

      视频没有加载出来的时候,点击视频播放,谷歌浏览器就会报这个错误。我也遇到了

    • Kk说道:

      我也遇到了点击视频的时候报The play() request was interrupted by a call to pause()这种错误,不知道怎么解决

    • symfony说道:

      解决了没?我也遇到了

    • symfony说道:

      我解决了
      if(video.buffered.end(0) < GetQueryString("playtime"))//GetQueryString("playtime")是当前点击位置,或者说是当前要跳转的位置
      alert("还没加载到这里,请耐心等待…");
      else{
      video.currentTime = GetQueryString("playtime");//已经加载到此处再设置currentTime
      }

  10. sylvana说道:

    通过百度搜索结果点击进入的页面,window.opener为什么是”DOMException”呢?请指点一下

  11. 路过支持了!说道:

    路过支持了!

  12. 才两个小时就有56次访问了

  13. pubu说道:

    路过支持了!