打开第二个Autodesk Forge Viewer实例时抛出ErrorCode:14错误如何解决?
错误原因
- 重复执行全局初始化:
Autodesk.Viewing.Initializer是全局单例方法,仅可在页面加载时执行一次,重复调用会污染已有的Viewer实例上下文,引发内存泄漏和画布尺寸识别异常。 - 未正确清理旧实例:销毁旧Viewer时没有调用官方提供的
viewer.finish()方法释放WebGL上下文、DOM绑定等资源,残留的旧实例画布被置0时会触发ErrorCode:14报错。 - 时序逻辑错误:
Autodesk.Viewing.Document.load被放在Initializer回调外部,会出现初始化未完成就尝试加载模型的时序问题,多实例场景下该问题出现概率会大幅提升。 - 多实例DOM冲突:如果是单页面同时存在多个Viewer的场景,所有实例绑定同一个id为
forgeViewer的DOM容器,会导致实例间DOM绑定互相覆盖,触发画布尺寸异常。
修复方案
- 全局仅初始化一次Forge环境:将
Autodesk.Viewing.Initializer调用逻辑移到页面初始化流程中,不要放在showViewer函数内重复执行。
- 全局仅初始化一次Forge环境:将
- 新增旧实例清理逻辑:每次创建新Viewer前,先检查是否存在已创建的实例,如有则执行资源释放:
if (instance.data.viewer) { instance.data.viewer.finish(); instance.data.viewer = null; // 清空DOM容器残留内容 document.getElementById('forgeViewer').innerHTML = ''; }
- 修正异步时序:将
Autodesk.Viewing.Document.load调用逻辑移到Initializer回调内部,保证初始化完成后再加载模型。
- 修正异步时序:将
- 多实例场景下每个Viewer对应唯一的DOM容器id,避免绑定冲突。
修正后的参考代码
// 全局初始化标记 let viewerInitDone = false; const initOptions = { env: 'AutodeskProduction', api: 'derivativeV2', getAccessToken: function(onTokenReady) { const token = viewerAccessToken; const timeInSeconds = 3600; onTokenReady(token, timeInSeconds); } }; // 页面加载时仅执行一次初始化 Autodesk.Viewing.Initializer(initOptions, () => { viewerInitDone = true; }); function showViewer(){ // 先清理旧实例 if (instance.data.viewer) { instance.data.viewer.finish(); instance.data.viewer = null; document.getElementById('forgeViewer').innerHTML = ''; } // 等待全局初始化完成 if (!viewerInitDone) { setTimeout(showViewer, 100); return; } const htmlDiv = document.getElementById('forgeViewer'); const viewer = new Autodesk.Viewing.GuiViewer3D(htmlDiv); instance.data.viewer = viewer; const startedCode = viewer.start(); viewer.setTheme("light-theme"); viewer.loadExtension("Autodesk.CustomDocumentBrowser").then(() => { viewer.loadExtension("Autodesk.Viewing.MarkupsCore"); viewer.loadExtension("Autodesk.Viewing.MarkupsGui"); }); if (startedCode > 0) { console.error('Failed to create a Viewer: WebGL not supported.'); $("#loadingStatus").html("Failed to create a Viewer: WebGL not supported."); return; } const documentId = `urn:${viewerUrn}`; Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure); function onDocumentLoadSuccess(viewerDocument) { const defaultModel = viewerDocument.getRoot().getDefaultGeometry(); viewer.loadDocumentNode(viewerDocument, defaultModel); } function onDocumentLoadFailure() { console.error('Failed fetching Forge manifest'); $("#loadingStatus").html("Failed fetching Forge manifest."); } }
内容的提问来源于stack exchange,提问作者Dr. Crunch
相关产品推荐
相关产品推荐

