XMLHttpRequest error when make api call in Forge app

I use Custom UI in my forge app. This app makes API calls to the external service.
I added my service URL to external.fetch.backend
(according to https://developer.atlassian.com/platform/forge/runtime-egress-permissions/)
API calls are made from the forge app.

Everything works file when I use forge tunnel and run react frontend locally. But, when I deploy my app, I get the next error:

ReferenceError: XMLHttpRequest is not defined
    at dispatchXhrRequest (index.js:12360:19)
    at new Promise (<anonymous>)
    at xhrAdapter (index.js:12351:10)
    at dispatchRequest (index.js:29724:10)
    at Axios.request (index.js:29563:15)
    at Axios.<computed> [as get] (index.js:29584:17)
    at Function.wrap [as get] (index.js:12203:15)
import Resolver from '@forge/resolver';
const axios = require('axios');
const resolver = new Resolver();
resolver.define("testFunction", async (({ payload, context })) => {
  const response = await axios.get('https://my-service-url/' + payload.id);
})
1 Like

Unfortunately, you cannot use axios, you will need to use @forge/fetch

2 Likes

Hi Remie!
I probably missed something, but from the official forge docs it’s possible

I don’t think you missed anything… but with ~10 years experience in the Atlassian Ecosystem I’m not really surprised if the documentation is not up-to-date.

Here is the thing: the whole premise of Forge is to create a “trusted” platform. That is why Atlassian has created a controlled execution environment. One of those things is to limit a lot of Node modules:

The following Node.js built-in modules are not supported:

async_hooks, child_process, cluster, constants, dgram, dns, domain, http2,
module, net, perf_hooks, readline, repl, sys, tls, trace_events, tty, v8,
vm, worker_threads.

(See https://developer.atlassian.com/platform/forge/runtime-reference/#javascript-environment)

If you look at the Axios code, there is a situation in which it detects if it should use XmlHttpRequest (in the browser) or the http module (in node).

I’m not sure what Atlassian has done, but for some reason, this line evaluates true:

if (typeof XMLHttpRequest !== 'undefined') {

while this line throws an error:

var request = new XMLHttpRequest();

Even if you manage to tell Axios to use http, given the list of excluded node modules in the sandboxed/isolated V8 engine that Forge is running, it will probably still not work (or will require a lot of effort to get it working).

That is why the Atlassian Forge team has created the @forge/api fetch function. This will allow you to make the required calls within the context of the controlled environment of Forge. Obviously, it does not have all the great features of Axios, but I guess that’s the entire point.

5 Likes

Hey @belokurbohdan :slight_smile:

I think @remie gave some good insight into why this isn’t straightforward. Thanks for that @remie!

In saying that, we do aim to support axios on a best effort basis. We try to ensure that our runtime has the fundamentals to support most SDKs and fetch wrappers.

I’m still trying to find out why this doesn’t work for you. I will follow up with the team and look at our end-to-end tests.

While we aim for this support, we shouldn’t be using axios in our documentation. I’m going to get this page rectified.

2 Likes

Thank you @rbolte and @remie for clear explanation of the problem. Hope this will be fixed soon.

Hi,
If we deploy from a windows machine we get a similar error “web-api:WebClient:0 http request failed XMLHttpRequest is not defined” but if we deploy the same code from Ubuntu (same computer with WSL2) it works. I just wanted to add just in case some experiences the same problem.

1 Like