Glory to Russia
Glory to Russia

Reputation: 18712

Is it possible to submit HTTP requests with WebAssembly?

I'm trying to submit a simple HTTP GET request in WebAssembly. For this purpose, I wrote this program (copied from Emscripten site with slight modifications):

#include <stdio.h>
#include <string.h>
#ifdef __EMSCRIPTEN__
#include <emscripten/fetch.h>
#include <emscripten.h>
#endif


void downloadSucceeded(emscripten_fetch_t *fetch) {
  printf("Finished downloading %llu bytes from URL %s.\n", fetch->numBytes, fetch->url);
  // The data is now available at fetch->data[0] through fetch->data[fetch->numBytes-1];
  emscripten_fetch_close(fetch); // Free data associated with the fetch.
}

void downloadFailed(emscripten_fetch_t *fetch) {
  printf("Downloading %s failed, HTTP failure status code: %d.\n", fetch->url, fetch->status);
  emscripten_fetch_close(fetch); // Also free data on failure.
}

unsigned int EMSCRIPTEN_KEEPALIVE GetRequest() {
  emscripten_fetch_attr_t attr;
  emscripten_fetch_attr_init(&attr);
  strcpy(attr.requestMethod, "GET");
  attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY;
  attr.onsuccess = downloadSucceeded;
  attr.onerror = downloadFailed;
  emscripten_fetch(&attr, "http://google.com");
  return 1;
}

When I compile it using $EMSCRIPTEN/emcc main.c -O1 -s MODULARIZE=1 -s WASM=1 -o main.js --emrun -s FETCH=1 I get the error

ERROR:root:FETCH not yet compatible with wasm (shared.make_fetch_worker is asm.js-specific)

Is there a way to run HTTP requests from WebAssembly? If yes, how can I do it?

Update 1: The following code attempts to send a GET request, but fails due to CORS issues.

#include <stdio.h>
#include <string.h>
#ifdef __EMSCRIPTEN__
#include <emscripten/fetch.h>
#include <emscripten.h>
#endif

unsigned int EMSCRIPTEN_KEEPALIVE GetRequest() {
  EM_ASM({
    var xhr = new XMLHttpRequest();
    xhr.open("GET", "http://google.com");
    xhr.send();
  });
  return 1;
}

Upvotes: 20

Views: 24589

Answers (3)

Sora2455
Sora2455

Reputation: 844

Unfortunately, there is no way to make a CORS request to Google.com from any website other than Google.com.

From MDN:

For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts. For example, XMLHttpRequest and the Fetch API follow the same-origin policy. This means that a web application using those APIs can only request HTTP resources from the same origin the application was loaded from, unless the response from the other origin includes the right CORS headers.

Google does not include those headers.

Because JavaScript/WebAssembly runs on the client's machine (not yours) you could do nasty things if this wasn't in place, like make POST requests to www.mybankingwebsite.com/makeTransaction with the client's cookies.

If you want to point the code you have in Update 1 to your own site, or run it on Node.js, it should work fine.

Upvotes: 1

sbc100
sbc100

Reputation: 3022

I recently ran across this issue with esmcripten fixed it in: https://github.com/kripken/emscripten/pull/7010

You should now be able to use FETCH=1 and WASM=1 together.

Upvotes: 8

ColinE
ColinE

Reputation: 70142

No, you cannot execute HTTP request from WebAssembly (or access DOM, or any other browser APIs). WebAssembly by itself doesn’t have any access to its host environment, hence it doesn’t have any built in IO capabilities.

You can however export functions from WebAssembly, and import functions from the host environment. This will allow you to make HTTP requests indirectly via the host.

Upvotes: 11

Related Questions