You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

第二次调用SOAP服务触发org.w3c.dom.DOMException异常求助

搞定WRONG_DOCUMENT_ERR异常:原因分析与修复建议

嘿,这个org.w3c.dom.DOMException: WRONG_DOCUMENT_ERR我之前做SOAP服务时也踩过坑!本质就是DOM节点被跨文档复用了——简单说,你把一个由A DOM文档创建的节点,硬塞到另一个完全不同的B DOM文档里,DOM规范可不允许这种“跨文档串门”的操作。结合你的代码,我梳理了几个最可能的触发原因:

1. setObj()里复用了旧请求的DOM节点(头号嫌疑)

看你的execute方法,每次调用都会新建new webreferences.CustomerWS.SaveNewCustomer(),这本身没问题,但如果你的setObj()方法里,存在把第一次请求生成的DOM节点直接赋值给第二次请求对象的逻辑,就会触发这个异常。

举个例子,如果setObj()里有类似这种代码:

// 第一次请求时把某个DOM节点存在全局/闭包变量里
let cachedNode = requestObject.someXmlNode;
// 第二次请求时直接把这个旧节点赋值给新的请求对象
customerRequestObjTest.customerInfo = cachedNode;

这时候cachedNode属于第一次请求对应的SOAP DOM文档,而新的customerRequestObjTest属于第二次请求的新DOM文档,跨文档赋值直接就会抛出WRONG_DOCUMENT_ERR。

2. SOAP服务客户端被意外复用(上下文没隔离)

你的initServiceClient方法返回的是this.webReference.getDefaultService(),如果getDefaultService()返回的是单例实例,那多次调用时会复用同一个SOAP客户端,而客户端内部的DOM文档上下文没被正确重置,导致第二次请求时混入了第一次请求的DOM节点残留。

3. 请求对象requestObject被跨请求复用

你的createRequest方法直接返回了传入的params(也就是requestObject),如果这个requestObject是被缓存起来跨请求复用的,它内部可能持有第一次请求的DOM节点引用,第二次调用时就会把旧节点带到新的请求文档里,触发异常。


针对性修复建议

  • 检查并修正setObj()逻辑:所有赋值给customerRequestObjTest的节点,必须是当前请求上下文创建的新节点。如果需要复用旧节点的内容,要用importNode把节点导入到当前文档中,比如:
    // 假设oldNode是来自其他文档的节点
    let currentDoc = svc.serviceClient.getDocument();
    let newNode = currentDoc.importNode(oldNode, true); // true表示深拷贝
    customerRequestObjTest.customerInfo = newNode;
    
  • 避免复用SOAP客户端单例:如果getDefaultService()返回的是单例,尝试每次调用initServiceClient时创建全新的服务实例,而不是依赖默认单例。
  • 确保请求对象每次都新建:在createRequest里不要直接返回params,而是基于params的内容创建一个新对象,彻底避免残留旧的DOM引用。

内容的提问来源于stack exchange,提问作者Adrian Setniewski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 06:34:35