Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not working in IE11 #415

Closed
omelhoro opened this issue Feb 17, 2019 · 18 comments · Fixed by JakeChampion/fetch#736
Closed

Not working in IE11 #415

omelhoro opened this issue Feb 17, 2019 · 18 comments · Fixed by JakeChampion/fetch#736

Comments

@omelhoro
Copy link

omelhoro commented Feb 17, 2019

When I'm importing fetch-mock (7.3.0) in IE11 I get an error Expected identifier which traces to the line function findStatus(val, { useSTD3ASCIIRules }) which seems to come from 'tr46' dependency.

Since this module is imported as a string in the 'es5/client-bundle.js', webpack can't transpile it correctly (and argument destructuring actually is also not an es5 feature at all).

@wheresrhys
Copy link
Owner

It'll be a while til I can look at this as will need to set up an ie11 environment and configure CI to run in ie11 too, which is not a trivial task. Would be great if you're able to work on a fix and submit a PR

@larsthorup
Copy link

I have been looking into this. On a project we're running our unit test suite in IE11 (and other browsers) and have not been able to upgrade to fetch-mock@7 for this and a variety of other reasons.

Today I was able to get it to work with these measures:

  • require('proxy-polyfill')
  • require('unorm')
  • transpiling with babel the following node_modules dependencies required directly or indirectly by fetch-mock@7 or isomorphic-fetch:
    • proxy-polyfill
    • tr46
    • webidl-conversions
    • whatwg-url
  • applying this patch to fetch-mock: triggerz@67424f3

I would like to submit the patch as a pull request, if there is a chance that it would get merged?

@wheresrhys
Copy link
Owner

Thanks Lars. I have a few questions

if ('_bodyInit' in response) {

Is this duck-typing to detect whatwg-fetch?

			response.bodyUsed = false;

Why was bodyUsed ever true here? Feels a bit weird to have to do this step and, as I don't test in ie11, a bit brittle to have the fix living in this library

How would you feel if I exposed the response constructor class, then you could do

const originalBOR = ResponseBuilder.prototype.buildObservableResponse

ResponseBuilder.prototype.buildObservableResponse = function (response) {
		if ('_bodyInit' in response) {
			// To support IE using proxy-polyfill and whatwg-fetch
			// ensure bodyUsed (of whatwg-fetch) to be properly initialized
			response.bodyUsed = false;
		}
                 return originalBOR.apply(this, response);
}

Could even publish your entire ie11 solution as an npm module in its own right

@larsthorup
Copy link

Hey Rhys, thank you for your quick reply!

Is this duck-typing to detect whatwg-fetch?

Yes, that's correct.

Why was bodyUsed ever true here?

It was not true. The problem is that the bodyUsed property is initially missing from the response object. When whatwg-fetch then later tries to set body.bodyUsed = true (https://github.com/github/fetch/blob/master/fetch.js#L160) through the Proxy it fails with the error "Cannot create property for a non-extensible object" because the Proxy'ed response object is freezed by now (https://github.com/GoogleChrome/proxy-polyfill/blob/master/README.md)

Feels a bit weird to have to do this step

Yes, I agree. Maybe the root cause here is that the Response object is not constructed correctly by fetch-mock (https://github.com/wheresrhys/fetch-mock/blob/master/src/lib/response-builder.js#L19)? Usually when using whatwg-fetch, bodyUsed is initialized to true (https://github.com/github/fetch/blob/master/fetch.js#L209) maybe ensured by prototypical inheritance of Response from Body (https://github.com/github/fetch/blob/master/fetch.js#L400) - this style of code is not very clear to me.

If we could initialize the Response object "more correctly" - that would be a better solution. Do you have any suggestions for how to do that?

@markcellus
Copy link

FYI I am running into the same original issue. Downgrading to fetch-mock 6.5.2 seems to fix the issue for me.

@sullivanpt
Copy link

sullivanpt commented Nov 6, 2019

I'm unsure what solution was decided on here? ResponseBuilder.prototype.buildObservableResponse is not exposed. whatwg-fetch still has the weird pattern that doesn't include bodyUsed when constructed with new. Is there something clever you all are doing with FetchMock.config.Request to work around this? I'm trying but so far I haven't hit on the right work-around. Thanks.

Minor update: figured out that whatwg-fetch initially sets Request.prototype.bodyUsed = false which is why it isn't available to proxy-pollyfill at time of Proxy creation.

Update: I created a PR in fetch-mock to try and address this; I'm not sure they'll accept it because this Proxy use case is edgy. Will keep our fingers crossed.

For the record my use case is phantomjs-prebuilt@2.1.7, fetch-mock@8.0.0-alpha.14, proxy-pollyfill@0.3.0 on CentOS 6.

sullivanpt added a commit to sullivanpt/fetch that referenced this issue Nov 6, 2019
Fixes wheresrhys/fetch-mock#415

Details: fetch-mock wraps the Response object in an ES6 Proxy to
provide useful test harness features such as flush.  However, on
ES5 browsers without fetch or Proxy support pollyfills must be used;
the proxy-pollyfill is unable to proxy an attribute unless it exists
on the object before the Proxy is created.  This change ensures
Response.bodyUsed exists on the instance, while maintaining the
semantic of setting Request.bodyUsed in the constructor before
_initBody is called.
@wheresrhys
Copy link
Owner

Thanks for submitting the PR to whatwg-fetch. Hope it gets accepted.

If it's not accepted I'll consider a PR to fix here by always setting to false on setup. There's a new major version of fetch-mock coming out soon, which gives me an opportunity to fix undocumented edge cases that people may, inadvertently, be relying on being buggy

@andrewmclagan
Copy link

andrewmclagan commented Nov 28, 2019

Great news. started to encounter the same issues on IE-11. As a side note we are also experiencing
Edge 17+ issues:

Edge 17.17134.0 (Windows 10.0.0) ERROR
  Expected ':'
  at webpack:///node_modules/fetch-mock/esm/client.mjs:2616:31 <- karma.tests.js:46306:31

We use it to test https://github.com/wp-headless/fetch if your interested in our test harness, happy to help.

@canrozanes
Copy link

As of fetch-mock v9.3.1, the issue still persist.

I first came across the problem by updating from v7.4.0 to v9.3.1. I traced back versions and it appears v8.0.0 breaks it.

The error I get on IE11 points to the line 5 of src/lib/request-utils.js the arrow function headersToArrays;

It appears the arrow function is not being transpiled properly to IE 11 supported syntax.

@sullivanpt
Copy link

Yeah, they never accepted the fetch PR. Would be great if you guys could go ask it gets accepted. Meanwhile I've been doing npm installs for fetch directly off the fork.

"whatwg-fetch": "git+https://github.com/sullivanpt/fetch.git#fetchmock-release"

@vire
Copy link

vire commented Apr 22, 2020

My findings with getting fetch-mock work in IE11 - it takes hours of debugging and the results are very disappointing.

tl;dr fetch-mock needs proxy and you can use https://github.com/GoogleChrome/proxy-polyfill but keep in mind it supports only a limited amount of traps -> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/has plus in combination with immer the universe will explode because immer will eventually call the GoogleChrome/proxy-polyfill which will result into an error immerjs/immer#514 (comment)

Proxy polyfill does not support trap 'has'

referenced here GoogleChrome/proxy-polyfill#49

@wheresrhys
Copy link
Owner

It seems like github have abandoned the fetch polyfill. I've raised an issue which may get looked at JakeChampion/fetch#777.

@andrewmclagan
Copy link

The reasoning is there is now such wide support for fetch and IE 11 is not being supported moving forward.

JakeChampion added a commit to JakeChampion/fetch that referenced this issue May 27, 2020
* Compatibility for fetch-mock using proxy-pollyfill
Fixes wheresrhys/fetch-mock#415

Details: fetch-mock wraps the Response object in an ES6 Proxy to
provide useful test harness features such as flush.  However, on
ES5 browsers without fetch or Proxy support pollyfills must be used;
the proxy-pollyfill is unable to proxy an attribute unless it exists
on the object before the Proxy is created.  This change ensures
Response.bodyUsed exists on the instance, while maintaining the
semantic of setting Request.bodyUsed in the constructor before
_initBody is called.

* Update fetch.js

Co-authored-by: Jake Champion <me@jakechampion.name>
@sullivanpt
Copy link

fetch accepted the PR. Thank you.

@carlosrberto
Copy link

carlosrberto commented Jun 29, 2020

still waiting github/fetch to release the fix to NPM

@carlosrberto
Copy link

carlosrberto commented Jun 29, 2020

The latest version of github/fetch is now in NPM.
For me now it works in IE11 using the latest github/fetch, latest fetch-mock and proxy-polyfill. But I still have to transpile fetch-mock in order to make it work.

@wheresrhys
Copy link
Owner

This section of the docs might help @carlosrberto http://www.wheresrhys.co.uk/fetch-mock/#usageimporting

Gonna close this issue... finally

@Finesse
Copy link

Finesse commented Oct 26, 2020

The es5 directory name and the website say that the code inside is ES5-compatible. But it's not (it has at least arrow expressions =>). This is the problem, and it's not solved.

cr313 added a commit to cr313/fetch-Js-flow that referenced this issue Apr 19, 2024
* Compatibility for fetch-mock using proxy-pollyfill
Fixes wheresrhys/fetch-mock#415

Details: fetch-mock wraps the Response object in an ES6 Proxy to
provide useful test harness features such as flush.  However, on
ES5 browsers without fetch or Proxy support pollyfills must be used;
the proxy-pollyfill is unable to proxy an attribute unless it exists
on the object before the Proxy is created.  This change ensures
Response.bodyUsed exists on the instance, while maintaining the
semantic of setting Request.bodyUsed in the constructor before
_initBody is called.

* Update fetch.js

Co-authored-by: Jake Champion <me@jakechampion.name>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

11 participants