THREE.js DRACOLoader报错:Uncaught SyntaxError: Unexpected token '<' 求助
DRACOLoader启用后出现
Uncaught SyntaxError: Unexpected token '<'错误的解决方案 核心原因分析
Uncaught SyntaxError: Unexpected token '<'通常是因为DRACOLoader请求的解码器文件返回了HTML内容(比如404错误页面),而非预期的JS/WASM解码器文件,导致JS解析时遇到HTML标签<报错。结合你的代码和场景,以下是具体排查和解决步骤:
1. 修正DRACOLoader解码器路径(最可能解决问题)
你代码中设置的解码器路径'three/examples/js/libs/draco/gltf'是相对路径,在构建工具(如Vite、Webpack)或服务器环境下,这个路径大概率无法正确指向解码器文件,导致请求404并返回HTML错误页。
解决方法:
- 首先将Draco解码器文件(
draco_decoder.js、draco_decoder.wasm、draco_encoder.js等)复制到项目的静态资源目录(比如Vite的public文件夹,或静态服务器的根目录下的draco/gltf子文件夹)。 - 修改路径为绝对路径:
const dracoLoader = new DRACOLoader(); // 假设解码器文件放在 /draco/gltf/ 路径下,可根据实际部署路径调整 dracoLoader.setDecoderPath('/draco/gltf/'); loader.setDRACOLoader(dracoLoader); - 验证:打开浏览器开发者工具的「网络」面板,刷新页面后查看
draco_decoder.js和draco_decoder.wasm的请求状态,确保返回200 OK。
2. 验证模型的Draco压缩格式
确认Blender导出的模型是标准的Draco压缩glTF:
- 用文本编辑器打开
sceneCOMP.gltf,检查是否包含字段:"extensionsUsed": ["KHR_draco_mesh_compression"],这是Draco压缩的官方标识。 - 重新导出模型时,在Blender的glTF导出设置中,确保勾选「Geometry」下的「Draco mesh compression」,并使用默认或合适的压缩参数。
3. 确保THREE.js版本一致性
GLTFLoader、DRACOLoader必须与THREE.js核心库版本完全一致,版本不匹配会导致解析逻辑冲突。比如如果安装的是three@0.158.0,则导入的examples模块也必须对应该版本。
4. 修正代码中的其他小问题
你的resize事件监听中存在变量名错误,会导致后续页面缩放时报错,需修改:
window.addEventListener('resize', function() { _camera.aspect = window.innerWidth / window.innerHeight; // 原代码用了未定义的camera,改为_camera _camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); });
完整修正后的代码示例
import * as THREE from 'three'; import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js' const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); const scene = new THREE.Scene(); // SETUP CAMERA var _camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); _camera.position.set(-10, 5, 15); _camera.target = new THREE.Vector3(0, 0, 0); _camera.lookAt(_camera.target); var _controls = new OrbitControls( _camera, renderer.domElement ); _controls.target = _camera.target; // CD OBJ PATH + LOADER const objURL= new URL('../../static/sceneCOMP.gltf', import.meta.url) const loader = new GLTFLoader(); const dracoLoader = new DRACOLoader(); // 修正解码器路径为绝对路径(根据实际部署路径调整) dracoLoader.setDecoderPath('/draco/gltf/'); loader.setDRACOLoader( dracoLoader ); var model; // LOAD OBJ loader.load( objURL.href, function ( glb ) { model = glb.scene; scene.add( model ); }, undefined, function ( error ) { console.error( error ); } ); // SETUP LIGHT const light = new THREE.AmbientLight( 0x404040, 1 ); // soft white light scene.add( light ) // DIRECTIONAL LIGHT + SHADOW const light2 = new THREE.DirectionalLight( 0xffffff, 1.3 ); light2.position.set( 0, 10, -5); // default; light shining from top light2.target.position.set(0, 0, 0); scene.add( light2 ); // ANIMATE WITH OBJ ANIMATION (MIXER + DELTA) function animate(time){ renderer.render(scene, _camera); } renderer.setAnimationLoop(animate); window.addEventListener('resize', function() { _camera.aspect = window.innerWidth / window.innerHeight; _camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); });
内容的提问来源于stack exchange,提问作者cobblestuv
相关产品推荐
相关产品推荐

