无法使用 Node.js Server 和 Three.js 加载文件(3D 模型)的文件路径

JDS*_*JDS 1 html javascript express three.js

我在使用本地主机 Node.js 测试服务器和 Three.js 库从计算机上的文件夹加载 3D 模型时遇到困难。

app.js:(我使用:命令在项目目录中通过命令行运行它node app.js

var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
var THREE = require('three');

app.get('/', function(req, res) {
    res.sendFile(__dirname + '/index.html');
});
io.on('connection', (socket) => {
  console.log('a user connected');
});

http.listen(3000, () => {
  console.log('listening on *:3000');
});
Run Code Online (Sandbox Code Playgroud)

index.html 的相关部分:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>Index.html title</title>

</head>

<body>
    
<script src="/socket.io/socket.io.js"></script> 
<script src="//threejs.org/build/three.js"></script> 
<script src="//threejs.org/examples/js/loaders/AMFLoader.js"></script>
<script src="//threejs.org/examples/js/controls/OrbitControls.js"></script>

<script>
    
    var socket = io();
    
    var camera, scene, renderer;

    init();

    function init() {
        scene = new THREE.Scene();
        scene.add( new THREE.AmbientLight( 0x999999 ) );
        camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 500 );
        camera.up.set( 0, 0, 1 );
        camera.position.set( 0, -9, 6 );
        camera.add( new THREE.PointLight( 0xffffff, 0.8 ) );
        scene.add( camera );
        var grid = new THREE.GridHelper( 25, 1.0, 0xffffff, 0x555555 );
        grid.rotateOnAxis( new THREE.Vector3( 1, 0, 0 ), 90 * ( Math.PI/180 ) );
        scene.add( grid );
        renderer = new THREE.WebGLRenderer( { antialias: true } );
        renderer.setClearColor( 0x999999 );
        renderer.setPixelRatio( window.devicePixelRatio );
        renderer.setSize( window.innerWidth, window.innerHeight );
        document.body.appendChild( renderer.domElement );
        
        /* everything up till here works */

        var loader = new THREE.AMFLoader(); 
        loader.load('/models/rook.amf', function ( amfobject ) { //'./models/rook.amf'

            scene.add( amfobject );
            render();

        } );

        /* ^^^ this is the part not working */

        var controls = new THREE.OrbitControls( camera, renderer.domElement );
        controls.addEventListener( 'change', render );
        controls.target.set( 0, 1.2, 2 );
        controls.update();
        window.addEventListener( 'resize', onWindowResize, false );

    }
    function onWindowResize() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize( window.innerWidth, window.innerHeight );
        render();
    }
    function render() {    
        renderer.render( scene, camera );
    }
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

我的项目目录:

在此输入图像描述

错误:

GET http://localhost:3000/models/rook.amf 404 (Not Found)
Run Code Online (Sandbox Code Playgroud)

如何在简单的服务器测试中使用 Node 和 Three.js 正确加载文件?

jsc*_*tro 5

大多数流行的 3D 格式扩展名(.glb、.gltf、.fbx、.dae、.amf...)都不是标准的MIME 类型,浏览器在操作这些文件时会特别小心,试图保护用户以防止危险行为。

因此,您需要配置 Web 服务器引擎以接受这些扩展,否则您在下载它们时会收到不同的 HTTP 错误。.amf 甚至不在此列表中,application/octet-stream所有其他情况的默认值也是如此。未知文件类型应使用此类型。 如果您从ASP.Net
应用程序 使用IIS服务器,请在web.config文件的节点中添加以下 xml 行:</system.webServer>

<system.webServer>
      ...
      <staticContent>
          <remove fileExtension=".mtl" />
          <mimeMap fileExtension=".mtl" mimeType="model/mtl" />
          <remove fileExtension=".obj" />
          <mimeMap fileExtension=".obj" mimeType="model/obj" />
          <remove fileExtension=".glb" />
          <mimeMap fileExtension=".glb" mimeType="model/gltf-binary" />
          <remove fileExtension=".gltf" />
          <mimeMap fileExtension=".gltf" mimeType="model/gltf+json" />
          <remove fileExtension=".fbx" />
          <mimeMap fileExtension=".fbx" mimeType="application/octet-stream" />
          <remove fileExtension=".amf" />
          <mimeMap fileExtension=".amf" mimeType="application/octet-stream" />
      </staticContent>
</system.webServer>
Run Code Online (Sandbox Code Playgroud)

如果您使用的是nginx服务器,请将以下行添加到对象中的nginx.conf文件中http

http {
    include /etc/nginx/mime.types;
    types {
        model/mtl mtl;
        model/obj obj;
        model/gltf+json gltf;
        model/gltf-binary glb;
        application/octet-stream fbx;
        application/octet-stream amf;
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

如果您使用的是Apache服务器,请将以下行添加到mime.types文件中:

model/mtl mtl
model/obj obj
model/gltf+json gltf
model/gltf-binary glb
application/octet-stream fbx
application/octet-stream amf
Run Code Online (Sandbox Code Playgroud)

对于任何其他 Web 服务器,您肯定可以轻松找到如何设置 MIME 类型配置。

编辑:在节点的情况下,检查您的文件server.js不包括对这些 MIME 类型的任何限制,大多数流行的server.js脚本都包含对非标准 MIME 类型的限制

EDIT2:我明白了,因为我怀疑它与 AMF 的 MIME 类型有关。我已将完整的解决方案发布在GitHub上发布了完整的解决方案

但需要改变的重要事项如下。

首先,更改您app.js要添加的 MIME 类型。

http {
    include /etc/nginx/mime.types;
    types {
        model/mtl mtl;
        model/obj obj;
        model/gltf+json gltf;
        model/gltf-binary glb;
        application/octet-stream fbx;
        application/octet-stream amf;
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

其次,由于最近Three.js(4月23日)发生了变化,使用AMF加载器,需要jszip模块。无需下载到本地,可以像其他js文件一样通过url使用。在我的项目中,index.html位于/express文件夹中,所以我的amf模型路径是../models/rock.amf

model/mtl mtl
model/obj obj
model/gltf+json gltf
model/gltf-binary glb
application/octet-stream fbx
application/octet-stream amf
Run Code Online (Sandbox Code Playgroud)

你说对了... 在此输入图像描述