在Three.js和Vue应用程序中使用glTFLoader时出现JSON中位置0处的意外字符<。

10
我想在我的Vue应用程序中使用GLTFLoader将.glTF文件加载到three.js中。 但是,当我尝试使用GLTFLoader加载.gltf文件时,控制台会持续显示以下错误信息:
“JSON中的位置0处出现意外的符号<”
我已经在Vue.js组件中实例化了Three.js和GLTFLoader。
经过一些研究,我发现这是因为glTF资产的HTTP请求返回了一个HTML网站。 我已经检查了网络响应,“modeltest.gltf”的内容类型是“text / html”。
Content-Type: text/html; charset=UTF-8
Status Code: 200 OK 
Request URL: http://localhost:8080/assets/modeltest.gltf

在另一个帖子中,类似问题的原因是Web服务器未提供glTF而是HTML内容(https://discourse.threejs.org/t/syntaxerror-unexpected-token-in-json-at-position-0/13810/3)。如果我在本地主机上运行应用程序,服务器仍然可能是问题的原因吗?

我已经尝试将我的3D模型转换为.obj格式,然后运行OBJLoader。但是当访问“modeltest.obj”文件时,加载器尝试解析HTML时会发生相同的情况。

如果我在终端中运行vue-cli-service serve,这个无法加载glTF文件是否与Vue正在运行的localhost服务器有关?如何使glTFLoader正确解析我的glTF文件,而不是将其解析为HTML?

我已经尝试将glTF文件加载到此站点,它可以正确加载https://gltf-viewer.donmccurdy.com/

非常感谢您的任何建议。谢谢阅读。

我的文件结构如下:

3D Model Path:
src/assets/modeltest.gltf
Vue Component Path:
src/components/ThreeTest.vue

我的Vue组件的代码如下:
<template>
    <div id="container"></div>
</template>

<script>
import * as Three from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

export default {
  name: 'ThreeTest',
  data() {
    return {
      camera: null,
      scene: null,
      renderer: null,
      mesh: null,
      model: null,
    }
  },
  methods: {
    init: function() {
      let container = document.getElementById('container');

      this.camera = new Three.PerspectiveCamera(70, container.clientWidth/container.clientHeight, 0.01, 10);
      this.camera.position.z = 1;

      this.scene = new Three.Scene();

      let geometry = new Three.BoxGeometry(0.2, 0.2, 0.2);
      let material = new Three.MeshNormalMaterial();

      this.mesh = new Three.Mesh(geometry, material);
      this.scene.add(this.mesh);

      this.renderer = new Three.WebGLRenderer({antialias: true});
      this.renderer.setSize(container.clientWidth, container.clientHeight);
      container.appendChild(this.renderer.domElement);

      // Instantiate a loader
      var loader = new GLTFLoader();

      // Load a glTF resource
      loader.load(
        // resource URL
        '../assets/modeltest.gltf',
        // called when the resource is loaded
        function ( gltf ) {     
          console.log(gltf);   
          this.scene.add( gltf.scene);
        },
        // called while loading is progressing
        function ( xhr ) {
          console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
        },
        // called when loading has errors
        function ( error ) {
          console.log(error)
          console.log( 'An error happened ' + error );
          
        }
      );
    },
    animate: function() {
        requestAnimationFrame(this.animate);
        this.mesh.rotation.x += 0.01;
        this.mesh.rotation.y += 0.02;
        this.renderer.render(this.scene, this.camera);
    }
  },
  mounted() {
      this.init();
      this.animate();
  }
}
</script>

<style scoped>
 #container{
   height: 100vh;
 }
</style>

你检查了请求的实际内容吗?如果你在网页浏览器中访问 http://localhost:8080/assets/modeltest.gltf,你会得到文件还是 HTML 页面? - Guy Incognito
通常在Vue中,静态文件是从public文件夹中提供的,而不是从src中提供的。 - Guy Incognito
感谢您的留言。当我访问 http://localhost:8080/assets/modeltest.gltf 时,我会得到一个HTML页面,即Vue应用程序。画布可以渲染,但没有gltf模型(只有盒子几何体)。 - anywhereseason
我已经在公共文件夹中放置了.gltf的副本,并在我的组件中指定路径为('../assets/modeltest.gltf'),但仍然出现相同的错误。 - anywhereseason
文件放错位置了。请查看 https://cli.vuejs.org/guide/html-and-static-assets.html#static-assets-handling 并确保URL可用(您可以通过浏览器直接访问URL下载它)。如果该文件位于公共文件夹的根目录,则URL应为 http://localhost:8080/modeltest.gltf - Guy Incognito
2个回答

6
modeltest.gltf放在public文件夹中,而不是其他组件目录中,这样可以解决您的问题。

0
在我的情况下,GLTF加载器还需要许可文件。一旦我的加载器能够访问许可文件以及.gltf文件或相关纹理,错误就消失了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接