请求:在React组件中嵌入Autodesk Forge Viewer的分步实现教程
没问题!我之前也踩过GitHub示例的坑,要么依赖太复杂要么缺关键步骤,给你一个纯React+Forge Viewer的极简实现,完全不用Redux——你已经拿到可用的URN了,直接跟着步骤来就行:
纯React组件嵌入Autodesk Forge Viewer(无Redux)分步指南
第一步:搭建基础React组件结构
先创建一个函数组件,核心是给Viewer预留一个带明确宽高的容器(Viewer必须有固定尺寸才能正常渲染),同时用useRef保存容器引用,用useEffect处理Viewer的初始化与销毁:
import { useEffect, useRef, useState } from 'react'; const ForgeViewer = ({ urn }) => { const viewerContainerRef = useRef(null); let viewerInstance = null; // 保存Viewer实例,方便后续销毁 const [accessToken, setAccessToken] = useState(null); const [isLoading, setIsLoading] = useState(true); const [loadError, setLoadError] = useState(null); // 组件卸载时销毁Viewer,避免内存泄漏 useEffect(() => { return () => { if (viewerInstance) { viewerInstance.tearDown(); viewerInstance.finish(); viewerInstance = null; } }; }, []); // 加载状态/错误提示 if (isLoading) return <div className="p-4">正在初始化Viewer...</div>; if (loadError) return <div className="p-4 text-red-500">{loadError}</div>; return ( <div ref={viewerContainerRef} style={{ width: '100%', height: '85vh', border: '1px solid #eee' }} /> ); }; export default ForgeViewer;
第二步:动态加载Forge Viewer资源
直接在index.html全局引入脚本会影响页面加载速度,我们改成在组件内按需动态加载Viewer的JS和CSS资源:
在刚才的组件里添加一个新的useEffect,用来加载资源并初始化Viewer:
// 新增:获取令牌并初始化Viewer useEffect(() => { if (!urn) return; // 从后端获取临时访问令牌(绝对不能把客户端密钥写在前端!) const fetchAccessToken = async () => { try { const res = await fetch('/api/forge/get-token'); // 替换成你的后端接口 const data = await res.json(); setAccessToken(data.access_token); } catch (err) { setLoadError('获取访问令牌失败,请检查后端服务'); setIsLoading(false); } }; fetchAccessToken(); // 等待令牌加载完成后初始化Viewer if (!accessToken) return; // 检查Viewer脚本是否已加载,避免重复加载 if (window.Autodesk?.Viewer?.Initializer) { initViewer(); return; } // 动态加载Viewer JS const viewerScript = document.createElement('script'); viewerScript.src = 'https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/viewer3D.min.js'; viewerScript.onload = () => { // 加载Viewer样式 const viewerStyle = document.createElement('link'); viewerStyle.rel = 'stylesheet'; viewerStyle.href = 'https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/style.min.css'; document.head.appendChild(viewerStyle); initViewer(); }; viewerScript.onerror = () => { setLoadError('加载Viewer资源失败,请检查网络'); setIsLoading(false); }; document.head.appendChild(viewerScript); // 核心初始化函数 function initViewer() { const initOptions = { env: 'AutodeskProduction', accessToken: accessToken, }; Autodesk.Viewing.Initializer(initOptions, () => { // 创建Viewer实例 viewerInstance = new Autodesk.Viewing.GuiViewer3D(viewerContainerRef.current, { extensions: [], // 可按需添加扩展,比如测量、标注等 }); viewerInstance.start(); // 加载模型 const documentId = `urn:${urn}`; Autodesk.Viewing.Document.load( documentId, (doc) => { const defaultViewable = doc.getRoot().getDefaultGeometry(); viewerInstance.loadDocumentNode(doc, defaultViewable); setIsLoading(false); }, (err) => { setLoadError(`加载模型失败:${err.message}`); setIsLoading(false); } ); }); } }, [urn, accessToken]);
第三步:后端令牌接口说明(关键!)
前端不能直接暴露Forge的客户端ID和密钥,必须通过后端生成临时访问令牌(有效期1小时),后端接口的核心逻辑(以Node.js为例)大概是这样:
// 后端示例:Express接口生成Forge令牌 const express = require('express'); const router = express.Router(); const { AuthClientTwoLegged } = require('forge-apis'); const FORGE_CLIENT_ID = '你的客户端ID'; const FORGE_CLIENT_SECRET = '你的客户端密钥'; router.get('/get-token', async (req, res) => { const authClient = new AuthClientTwoLegged( FORGE_CLIENT_ID, FORGE_CLIENT_SECRET, ['viewables:read'], // 只申请模型查看权限,最小权限原则 true ); try { const credentials = await authClient.authenticate(); res.json({ access_token: credentials.access_token, expires_in: credentials.expires_in }); } catch (err) { res.status(500).json({ error: err.message }); } }); module.exports = router;
第四步:组件使用示例
在父组件里直接传入你的模型URN即可:
import ForgeViewer from './ForgeViewer'; function App() { const modelUrn = '你的模型URN'; // 比如:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6bXktYnVza2V0L215LW1vZGVsLmR3Zw return ( <div className="min-h-screen p-6"> <h1 className="text-2xl font-bold mb-4">我的Forge模型查看器</h1> <ForgeViewer urn={modelUrn} /> </div> ); } export default App;
常见问题排查
- Viewer空白不显示:检查容器是否有明确宽高,令牌是否包含
viewables:read权限,URN是否正确(无需额外base64编码,直接用你拿到的可传入Viewer的URN)。 - 资源加载失败:把CDN链接里的
7.*换成具体版本号(比如7.71.0),避免版本兼容问题,可在Forge官网查看最新稳定版。 - 内存泄漏:务必在组件卸载时调用
tearDown()和finish()销毁Viewer实例,否则多次渲染会导致浏览器崩溃。
内容的提问来源于stack exchange,提问作者Cesare Caoduro
相关产品推荐
相关产品推荐

