XMLHttpRequest issues when running Babylonjs on a server (nodejs and TypeScript)

Hello!
I need nullengine and typescript based project for my perpose, but I have a problem (as it is server-side project,there are no playground code).
As I have seen in previous forums[Basic setup of running Babylon.js NullEngine with server side (node.js) using TypeScript], with a small sample it works, but when I add the code for loading models, bjs requires xhr2.
Therefore, the following code will not work.

import { NullEngine, Scene, SceneLoader } from "@babylonjs/core";
import "@babylonjs/loaders/glTF";

export const main = () => {
  const engine = new NullEngine();
  const scene = new Scene(engine);
  SceneLoader.ImportMesh("", "sample/", "dummy2.babylon", scene, () => {
    console.log("success!");
  });
};

The problem is that the project is in Typescript, require() is not available, so I use import syntax, but XMLHttpRequest is inferred to be of type “any” and I can’t avoid this.

import { NullEngine, Scene, SceneLoader } from "@babylonjs/core";
import "@babylonjs/loaders/glTF";
import XMLHttpRequest from "xhr2"; // Error : XMLHttpRequest has an implicit `any` type

export const main = () => {
  global.XMLHttpRequest = XMLHttpRequest;
  const engine = new NullEngine();
  const scene = new Scene(engine);
  SceneLoader.ImportMesh("", "sample/", "dummy2.babylon", scene, () => {
    console.log("success!");
  });
};

Furthermore, if the code were to work with strict: false (Yeah, this is not good), the following error would also occur.

BJS - [19:19:52]: Babylon.js v5.37.0 - Null engine
/home/udemegane/workspace/bjs-serverside-sample/node_modules/xhr2/lib/xhr2.js:281
            throw new NetworkError(`Unsupported protocol ${this._url.protocol}`);
                  ^
NetworkError
    at XMLHttpRequest.send (/home/udemegane/workspace/bjs-serverside-sample/node_modules/xhr2/lib/xhr2.js:281:19)
    at WebRequest.send (file:///home/udemegane/workspace/bjs-serverside-sample/lts/core/generated/Misc/webRequest.ts:167:19)
    at retryLoop (file:///home/udemegane/workspace/bjs-serverside-sample/lts/core/generated/Misc/fileTools.ts:525:21)
    at requestFile (file:///home/udemegane/workspace/bjs-serverside-sample/lts/core/generated/Misc/fileTools.ts:527:9)
    at RequestFile (file:///home/udemegane/workspace/bjs-serverside-sample/lts/core/generated/Misc/fileTools.ts:561:9)
    at LoadFile (file:///home/udemegane/workspace/bjs-serverside-sample/lts/core/generated/Misc/fileTools.ts:384:12)
    at Scene._loadFile (file:///home/udemegane/workspace/bjs-serverside-sample/lts/core/generated/scene.ts:4495:25)
    at manifestChecked (file:///home/udemegane/workspace/bjs-serverside-sample/lts/core/generated/Loading/sceneLoader.ts:583:25)
    at Function._LoadData (file:///home/udemegane/workspace/bjs-serverside-sample/lts/core/generated/Loading/sceneLoader.ts:605:13)
    at Function.ImportMesh (file:///home/udemegane/workspace/bjs-serverside-sample/lts/core/generated/Loading/sceneLoader.ts:765:28)

Looking at the babylonjs source code, there should be a way around this since the Loader unit test is done on the server side, but I don’t know.
Can someone please help!!! Thanks!

Try this:

import xhr2 from 'xhr2'

// @ts-ignore
global.XMLHttpRequest = xhr2.XMLHttpRequest

EDIT: Oops yeah you probably did this :smiley:

1 Like

About the message Unsupported protocol ${this._url.protocol} even if your file is local the import must be done threw the http protocol so your first parameter has to be set :

SceneLoader.ImportMesh("http://localhost/XXX", "sample/", "dummy2.babylon", scene, () => {
    console.log("success!");
});
3 Likes

Was just about to type this as well. You basically need a web server (even static) running.

I had completely forgotten about it :upside_down_face: Thank you!

I delivered from the local server and everything worked fine. Thank you!

1 Like