lquixada / cross-fetch

Universal WHATWG Fetch API for Node, Browsers and React Native.
MIT License
1.67k stars 104 forks source link

Cross-fetch is not usable in service workers #78

Closed pimterry closed 1 year ago

pimterry commented 4 years ago

I'm using this library (via https://github.com/prisma-labs/graphql-request) and it fails to make requests when used within a browser service worker. More specifically, it throws:

ReferenceError: XMLHttpRequest is not defined
    at browser-ponyfill.js:463
    at new Promise (<anonymous>)
    at Object.fetch [as default] (browser-ponyfill.js:455)
    at GraphQLClient.<anonymous> (index.ts:87)
    at step (createRequestBody.ts:45)
    at Object.next (createRequestBody.ts:45)
    at createRequestBody.ts:45
    at new Promise (<anonymous>)
    at createRequestBody.ts:45
    at GraphQLClient.request (index.ts:73)

Service workers do always have fetch available, but they don't have XMLHttpRequest. See https://github.com/whatwg/xhr/issues/19 for some background from the spec discussion.

Because they are a browser environment though, https://github.com/lquixada/cross-fetch/blob/master/dist/browser-ponyfill.js from this library is used, which incorrectly seems to assume XHR is always available in all modern browser environments.

I think all that's required here is to fall back to the built-in Fetch that is available in this case.

madeleineostoja commented 4 years ago

I've also hit this issue, but in a different context — Sapper also has fetch available in its SSR environment but not XMLHttpRequest, and one of my dependencies (prismic-javascript) uses cross-fetch, making it unusable.

abnemo commented 3 years ago

Hello guys! I discovered a cool project called supabase. However, I wanted to use their javascript client supabase-js with deno, but XMLHttpRequest is not defined there too =(

jcs224 commented 3 years ago

Hopefully, this will be fixed now. A dependency for this library was just updated for this situation. https://github.com/github/fetch/pull/967

abnemo commented 3 years ago

Any plans for the next release with updated dependencies?

Nick-Mazuk commented 3 years ago

Running into this issue on Cloudflare Workers as well. Any dependency that uses cross-fetch cannot be used on Cloudflare Workers right now.

ntinkler-calendly commented 2 years ago

Can confirm that I also see this issue when using packages that depend on cross-fetch in chrome-extension background scripts (Manifest v3, service worker based).

Cross-fetch blows up trying to use XHR to implement fetch when the environment provides fetch but not XHR.

Example error

"ReferenceError: XMLHttpRequest is not defined
    at chrome-extension://dohbfkgabajhohdidhmhhpfagifoacnk/background.js:1716:23
    at new Promise (<anonymous>)
    at fetch (chrome-extension://dohbfkgabajhohdidhmhhpfagifoacnk/background.js:1709:18)
arun3528 commented 2 years ago

Has anyone found any alternate library or make cross fetch work in service worker

ntinkler-calendly commented 2 years ago

Has anyone found any alternate library or make cross fetch work in service worker

Given that service workers are only present in browsers that provide fetch natively, I've begun patching packages locally (yarn patch - in my case) and just ripping cross-fetch out when I build for service worker contexts. It feels very silly that this library doesn't simply expose the native implementation when it's present, but they might have a reason for falling back to XHR.

Either way - given that there doesn't appear to be any effort to fix this here, and even if fixed, you'll have to wait for 3rd party libraries to pick up the update, removing it is the only sane path forward I found.

It's a pain in the butt, but given that most libraries import this using either

import fetch from 'cross-fetch'
// or
const fetch = require('cross-fetch')

Just deleting the line before bundling will cause later references to pick up the global native implementation and work as expected.

arun3528 commented 2 years ago

Thanks a lot that worked for me as it a fresh project

On Fri, Feb 18, 2022, 11:57 AM Nate Tinkler @.***> wrote:

Has anyone found any alternate library or make cross fetch work in service worker

Given that service workers are only present in browsers that provide fetch natively, I've begun patching packages locally (yarn patch - in my case) and just ripping cross-fetch out when I build for service worker contexts. It feels very silly that this library doesn't simply expose the native implementation when it's present, but they might have a reason for falling back to XHR.

Either way - given that there doesn't appear to be any effort to fix this here, and even if fixed, you'll have to wait for 3rd party libraries to pick up the update, removing it is the only sane path forward I found.

It's a pain in the butt, but given that most libraries import this using either

import fetch from 'cross-fetch' // or const fetch = require('cross-fetch')

Just deleting the line before bundling will cause later references to pick up the global native implementation and work as expected.

— Reply to this email directly, view it on GitHub https://github.com/lquixada/cross-fetch/issues/78#issuecomment-1044838328, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA5XBPRVGXIQR5W465HAIG3U3Z27ZANCNFSM4SE56JCA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you commented.Message ID: @.***>

karol-cf commented 2 years ago

Hi,

I have this issue when trying to use Supabase in an MV3 Chrome Extension's service workers. I'm using an example I've found in this YouTube video (he's using MV2, which utilizes a background page, instead of service workers, so the issue is not present there). The extension allows you to sign up and log in with Supabase in a new Chrome tab. I've got a bundled version of supabase-js in my project. The supabase-js library is imported in the service worker and I create a client (as you can see on the screenshot below, I've tried binding the fetch as well). Whenever the user wants to authenticate, I send a message through the message passing API to my service worker and call various supabase.auth methods. Every time the signUp method is called, for example, I get "ReferenceError: XMLHttpRequest is not defined" and the method does not proceed further (on the third screenshot I've tried signing up and it threw an error).

image image (1) image (2)

The only solution, that I think might work is removing the cross-fetch import from your lib and then bundling it, as mentioned above. Because of the MV3 requirements, I need that bundled js file anyway. However, I'd much rather not do that, because I don't think that this is a clean way of solving the problem. Any other ideas?

dax70 commented 1 year ago

Same issue with Cloudflare workers and noticed it's been open for 2+ years.

Any concerns in uncommenting line: 49? https://github.com/lquixada/cross-fetch/blob/main/rollup.config.js#L49

var ctx = global.fetch ? global : __self__;

I am using a package that uses cross-fetch.

lquixada commented 1 year ago

I've been working on version 4 of cross-fetch to fix this issue. If anyone's interested, please run npm install cross-fetch@latest-v4.x in your project and give it a try. Let me know if any issues come up.

lquixada commented 1 year ago

Version 4 has been officially released with the fix. Please check it out: npm install cross-fetch.