Running the quick start hello method in a browser returns _Loading..._, not the expected form

The quick start hello sample is straightforward and works as expected, but I’m running into issues when trying accessing it from the browser, at least in my environment.

What I did:

 ~/projects $ cd hello/
 ~/projects/hello $ npm install
npm WARN hello@0.1.0 No repository field.
npm WARN hello@0.1.0 No license field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.12 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.12: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

audited 5457 packages in 1.859s

7 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

 ~/projects/hello $ dfx build
Building canister hello
Building frontend
Bundling frontend assets in the canister
 ~/projects/hello $ dfx start --background
⠁ Starting up the client...
Apr 12 03:28:59.324 INFO Dfinity Replica Started
Apr 12 03:28:59.324 INFO Existing node ID: 15906094607276922983
client address: "http://localhost:34789"
binding to: V4(127.0.0.1:8000)
client(s): http://localhost:34789/
Apr 12 03:28:59.325 INFO Using path '/home/admin/projects/hello/.dfx/state/replicated_state' to manage local state, StateManager: 1
Apr 12 03:28:59.326 INFO ConnManager: node_id = 15906094607276922983, node_ip = "127.0.0.1", Application: TransportConnectionMgr
  Internet Computer client started...
 ~/projects/hello $ dfx canister install --all
Installing code for canister hello, with canister_id ic:3CB94E949D868FF0D0
Apr 12 03:29:45.413 INFO Successfully inserted an ingress message into IngressPool, Application: ArtifactPool
Apr 12 03:29:46.361 INFO Created checkpoint @93 in 492.183µs, StateManager: 1
 ~/projects/hello $ dfx canister call hello greet "there" --type string
Apr 12 03:29:53.620 INFO Successfully inserted an ingress message into IngressPool, Application: ArtifactPool
Apr 12 03:29:54.146 INFO Created checkpoint @109 in 5.132263ms, StateManager: 1
("Hello, there!")

So far so good, but how calling the method greet from a browser? I tried this:

 ~/projects/hello $ curl -v http://127.0.0.1:8000/candid?canisterId=ic:3CB94E949D868FF0D0
*   Trying 127.0.0.1:8000...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)
> GET /candid?canisterId=ic:3CB94E949D868FF0D0 HTTP/1.1
> Host: 127.0.0.1:8000
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-length: 337
< etag: "df79d5:151:1:0"
< accept-ranges: bytes
< content-type: text/html
< last-modified: Thu, 01 Jan 1970 00:00:01 GMT
< content-disposition: inline; filename="index.html"
< date: Sun, 12 Apr 2020 03:30:19 GMT
<
<html>
<head>
    <meta charset="UTF-8">
    <title>DFINITY Canister Candid UI</title>
</head>
<body>
  <app id="app">
    <h1 id="title">Service</h1>
    <div>
      This service has the following methods:
      <ul id="methods">
      </ul>
    </div>
  </app>
<script type="text/javascript" src="../index.js"></script></body>
</html>
* Connection #0 to host 127.0.0.1 left intact

And this:

 ~/projects/hello $ curl -v http://127.0.0.1:8000/?canisterId=ic:3CB94E949D868FF0D0
*   Trying 127.0.0.1:8000...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)
> GET /?canisterId=ic:3CB94E949D868FF0D0 HTTP/1.1
> Host: 127.0.0.1:8000
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-length: 407
< content-type: text/html
< last-modified: Thu, 01 Jan 1970 00:00:01 GMT
< accept-ranges: bytes
< content-disposition: inline; filename="index.html"
< etag: "df79d7:197:1:0"
< date: Sun, 12 Apr 2020 03:30:34 GMT
<
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width">
  <title>IC Canister Bootstrap</title>
  <style>.ic_progress { display: block; margin: 50vh auto; width: 25vw; }</style>
</head>
<body>
  <app id="app"><progress class="ic_progress" id="ic-progress">Loading...</progress></app>
<script type="text/javascript" src="index.js"></script></body>
</html>
* Connection #0 to host 127.0.0.1 left intact
 ~/projects/hello $

HTTP RC is 200, but the returned HTML doesn’t seem to be right; the methods list is empty and the progress continues to be Loading…; am I missing something?

Thanks.

2 Likes

Hi samoht, welcome! These urls are for a GUI web browser, if you pop them in a desktop browser like firefox or chrome they should load fine.

http://127.0.0.1:8000/candid?canisterId=ic:<canister_id>

gives you a built-in form to test public canister calls.

http://127.0.0.1:8000/?canisterId=ic:<canister_id>

gives you the application interface you created in the source files.

They need javascript to load the default page content, so make sure that’s enabled. Curl won’t load this so it doesn’t get that far.

——

If you want to interact directly in the console you can keep using dfx for this, like so:

dfx canister call hello greet ‘(“samoht”)’

2 Likes

Thanks @Ori, I guess the subject line is misleading; I apologize, I’ll change it. The problem is a different one; using those URLs doesn’t return the expected HTML.

1 Like

After giving this some more thoughts, I was thinking that because the node was started in background I might miss out on some error logging, so I started the node again:

 ~/projects/hello $ dfx -v start
⠁ Starting up the client...
Apr 12 18:03:28.008 INFO Dfinity Replica Started
Apr 12 18:03:28.008 INFO Existing node ID: 6105257025598759955
client address: "http://localhost:34051"
Apr 12 18:03:28.009 INFO Using path '/home/admin/projects/hello/.dfx/state/replicated_state' to manage local state, StateManager: 1
binding to: V4(127.0.0.1:8000)
⠉ Client bound at 34051
⠚ Client bound at 34051
Apr 12 18:03:28.282 INFO Recovered checkpoint @97 in 273.599291ms, StateManager: 1
Apr 12 18:03:28.283 INFO ConnManager: node_id = 6105257025598759955, node_ip = "127.0.0.1", Application: TransportConnectionMgr
Apr 12 18:03:28.283 INFO ConnManager::init_client(): client_type = P2P, Application: TransportConnectionMgr
  Internet Computer client started...

Everything seems fine, but the HTML returned still shows Loading…:

 ~/projects/hello $ curl http://127.0.0.1:8000/?canisterId=ic:3CB94E949D868FF0D0
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width">
  <title>IC Canister Bootstrap</title>
  <style>.ic_progress { display: block; margin: 50vh auto; width: 25vw; }</style>
</head>
<body>
  <app id="app"><progress class="ic_progress" id="ic-progress">Loading...</progress></app>
<script type="text/javascript" src="index.js"></script></body>
</html>

Anyone any clue? Thanks.

1 Like

Starting the node in verbose mode results in messages

Apr 12 15:14:58.860 INFO binding to: V4(127.0.0.1:8000), version: 0.5.5
Apr 12 15:14:58.860 INFO client(s): http://localhost:46391/, version: 0.5.5
Apr 12 15:14:58.923 DEBG Request (0B) to replica (http://localhost:46391/api/v1/read), version: 0.5.5
Apr 12 15:14:58.925 DEBG Request (0B) to replica (http://localhost:46391/api/v1/read), version: 0.5.5
Apr 12 15:14:59.126 DEBG Response (18B) with status code 405, version: 0.5.5
Apr 12 15:14:59.127 DEBG Response (18B) with status code 405, version: 0.5.5

logged; a request to replica process running on port 46391 returns a little bit more nuanced message:

 ~/projects/hello $ curl -v http://localhost:46391/api/v1/read
*   Trying ::1:46391...
* TCP_NODELAY set
* connect to ::1 port 46391 failed: Connection refused
*   Trying 127.0.0.1:46391...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 46391 (#0)
> GET /api/v1/read HTTP/1.1
> Host: localhost:46391
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 405 Method Not Allowed
< Server: tiny-http (Rust)
< Date: Sun, 12 Apr 2020 19:27:34 GMT
< Content-Type: text/plain; charset=UTF-8
< Access-Control-Allow-Methods: POST, GET
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Headers: Accept, Authorization, Content-Type
< Content-Length: 18
<
* Connection #0 to host localhost left intact
Unsupported method

Wondering if this is at all related to the problems I’m facing?

Is there a better way to debug this?

1 Like

That does actually look like the expected html output to me, the ul and app tags are populated by javascript later on (again curl won’t execute the javascript I shouldn’t think).

So you’re getting the same “Loading…” message in a GUI browser like chrome with javascript enabled?

3 Likes

Thanks @Ori, excellent pointer.

As you might have guessed, I was using curl (and a text browser that actually supports JS) because the system I’m using doesn’t have a window manager running. Apparently, that’s not enough, one need a modern web browser to execute the client-side JS.

Accessing the URL from a remote, Chromium-based browser resulted in error:

An error happened:
TypeError: Cannot read property 'digest' of undefined
    at f (http://192.168.115.2:8000/index.js:2:60223)
    at h (http://192.168.115.2:8000/index.js:2:60388)
    at http://192.168.115.2:8000/index.js:2:60619
    at Array.map ()
    at Object.t.requestIdOf (http://192.168.115.2:8000/index.js:2:60594)
    at a (http://192.168.115.2:8000/index.js:2:107688)
    at http://192.168.115.2:8000/index.js:2:142405
    at async t.HttpAgent.read (http://192.168.115.2:8000/index.js:2:141039)
    at async _loadJs (http://192.168.115.2:8000/index.js:2:88876)
    at async _main (http://192.168.115.2:8000/index.js:2:89971)

I haven’t figured out jet why that happens, but switching to Firefox resulted in the expected rendering of the page. Seems like it is time for me considering switching the browser…

1 Like

No problem samoht. There’s still plenty of scope for you to build IC services, which don’t need a front end.

If your environment has node installed and you don’t want dfx to build the front end, you can run dfx build --skip-frontend, or just remove/rename the package.json file in your project.

Re digest, the browser might be lacking support for something there, but it could be worth you contacting support@dfinity.org with this and letting them know which browser it is.

1 Like