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

请求:在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 13:37:46