I want to load a .glTF file into three.js using the GLTFLoader in my Vue app. However, I continue to get this error in the console when I try to load the .gltf file with the GLTFLoader:
Unexpected token < in JSON at position 0
I have instantiated both Three.js and the GLTFLoader inside a Vue.js component.
After some research, I can see this is because the HTTP request for the glTF asset returns a HTML site. I have checked the network response and 'modeltest.gltf' content type is 'text/html'.
Content-Type: text/html; charset=UTF-8
Status Code: 200 OK
Request URL: http://localhost:8080/assets/modeltest.gltf
Following a different thread, the cause of a similar problem was that the web server does not serve a glTF but HTML content (https://discourse.threejs.org/t/syntaxerror-unexpected-token-in-json-at-position-0/13810/3). Can the server still be the cause of the problem if I am running the app on local host?
I have tried converting my 3d model into .obj format and then run the OBJLoader. However the same thing happens as the loader attempts to parse HTML when accessing the 'modeltest.obj' file.
Is this failure to load glTF connected to the server Vue is running on localhost when I run vue-cli-service serve
in terminal? How can I get the glTFLoader to parse my glTF file correctly, not as a HTML?
I have tried loading the glTF file onto this site and it loads correctly https://gltf-viewer.donmccurdy.com/
Any advice would be much appreciated. Thank you for reading.
My file structure looks like:
3D Model Path:
src/assets/modeltest.gltf
Vue Component Path:
src/components/ThreeTest.vue
The code for my Vue component looks like:
<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>
Put the
modeltest.gltf
in the public folder rather than any other component directory, that would resolve your issue.