What is the canonical procedure to fetch() a resource from localhost in a background script?

103 views
Skip to first unread message

guest271314

unread,
Aug 23, 2020, 2:08:44 AM8/23/20
to Chromium Extensions
What is the canonical procedure to fetch() a resource from localhost in a background script?


wOxxOm

unread,
Aug 23, 2020, 10:07:03 AM8/23/20
to Chromium Extensions, guest...@gmail.com
It's the standard fetch(url), but your manifest.json's "permissions" should contain a correct pattern for the url. A common mistake is to specify the port. Don't specify the port. Example: "permissions": ["*://localhost/"]

See https://developer.chrome.com/extensions/xhr

guest271314

unread,
Aug 23, 2020, 10:20:34 AM8/23/20
to Chromium Extensions, wOxxOm, guest271314
Still getting TypeError

background.js:16 GET http://localhost:8000/?start=true net::ERR_EMPTY_RESPONSE
(anonymous) @ background.js:16
background.js:40

This is a background script in a Native Messaging application. 

If it would be helpful can post the relevant code here. 

guest271314

unread,
Aug 23, 2020, 10:30:57 AM8/23/20
to Chromium Extensions, wOxxOm, guest271314
Interestingly if set permissions to localhost the code runs exactly once before the errors re-commence Screenshot_2020-08-22_21-56-41.png

On Sunday, August 23, 2020 at 7:07:03 AM UTC-7 wOxxOm wrote:

guest271314

unread,
Aug 23, 2020, 10:32:09 AM8/23/20
to Chromium Extensions, wOxxOm, guest271314
Can you create a minimal, complete, verifiable example to demonstrate?

On Sunday, August 23, 2020 at 7:07:03 AM UTC-7 wOxxOm wrote:

guest271314

unread,
Aug 23, 2020, 12:50:44 PM8/23/20
to Chromium Extensions, wOxxOm, guest271314
If the code is run at console fetch() response is "ok", an error is thrown when running in background.js. Why?Screenshot_2020-08-23_09-50-19.png

On Sunday, August 23, 2020 at 7:07:03 AM UTC-7 wOxxOm wrote:

guest271314

unread,
Aug 23, 2020, 1:41:13 PM8/23/20
to Chromium Extensions, wOxxOm, guest271314
Solved.

Evidently

chrome.runtime.sendNativeMessage(id, {}, async _ => {
   fetch() 
});

runs before the bash script that is used for Native Messaging host completes at

    php -S localhost:8000 -t /path/to/host/ & sendMessage # note use of &

where sendMessage send a simple message to background.js.

The solution is to await 15 milliseconds before calling fetch()

        await new Promise(resolve => setTimeout(resolve, 15));
        try {
        const response = await fetch(
          {
            // cache: 'no-store',
            mode: 'cors',
            method: 'get',
            signal,
          }
        );

9 and occasionally 10 milliseconds still throws network error.

Or, make HEAD request until Response.ok from server

        for await (const request of (async function* stream() {
          while (true) {
            try {
              if ((await fetch('http://localhost:8000', {method: 'HEAD'})).ok) break;
            } catch(e) {
              console.warn(e.message);
              yield;
            }
          }
        })());

then make the GET request.






On Sunday, August 23, 2020 at 7:07:03 AM UTC-7 wOxxOm wrote:

Simeon Vincent

unread,
Aug 24, 2020, 5:05:41 PM8/24/20
to guest271314, Chromium Extensions, wOxxOm
This doesn't sound like a stable solution. The 15 ms timeout you describe sounds like it's highly dependent on system-specific constraints and therefore will likely not work well on other devices or environments.

I'd recommend having the Bash script that acts as the native messaging host send a message to the extension to notify the extension that the web server is ready to receive requests. Alternatively, add some guards to the while(true) to account for runaway processes, improperly configured local environments, etc to avoid an infinite loop where you keep attempting to fetch from a server that will never respond.

Simeon - @dotproto
Developer Advocate for Chrome Extensions


--
You received this message because you are subscribed to the Google Groups "Chromium Extensions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-extens...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/chromium-extensions/6d820b16-a258-4abd-a29b-107d3495ba5cn%40chromium.org.

guest271314

unread,
Aug 24, 2020, 10:47:32 PM8/24/20
to Chromium Extensions, Simeon Vincent, Chromium Extensions, wOxxOm, guest271314
> This doesn't sound like a stable solution. The 15 ms timeout you describe sounds like it's highly dependent on system-specific constraints and therefore will likely not work well on other devices or environments.

Abandoned the 15 millisecond timeout approach.

> I'd recommend having the Bash script that acts as the native messaging host send a message to the extension to notify the extension that the web server is ready to receive requests.

That actually oes occur at

  php -S localhost:8000 -t /path/to/host/ & sendMessage

> Alternatively, add some guards to the while(true) to account for runaway processes, improperly configured local environments, etc to avoid an infinite loop where you keep attempting to fetch from a server that will never respond.

Note the AbortController set at fetch() init object. 

The code is several proof-of-concepts https://github.com/guest271314/captureSystemAudio to workaround a Chromium WontFix https://bugs.chromium.org/p/chromium/issues/detail?id=931749#c_ts1597971101. All feedback, critical or other wise, and improvements welcome.

The full code https://github.com/wasmerio/php-ext-wasm/issues/121#issuecomment-678898047 which you can test for yourself,  meaning test until the code breaks.

Ideally no server should need to be used at all https://bugs.chromium.org/p/chromium/issues/detail?id=1115640, though we are not there yet in a single cohesive API.
Reply all
Reply to author
Forward
0 new messages