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

IE11 support for server-side Blazor #9436

Open
zerocore2340 opened this issue Apr 16, 2019 · 51 comments
Open

IE11 support for server-side Blazor #9436

zerocore2340 opened this issue Apr 16, 2019 · 51 comments

Comments

@zerocore2340
Copy link

@zerocore2340 zerocore2340 commented Apr 16, 2019

Creating a default "Razor Component" Project and trying to access it from IE 11 doesn't seem to work.

Steps to reproduce the behavior:

  1. Create a new "Razor Component" project
  2. Run
  3. Access it from IE11

Expected behavior / Error
The counter page shows up but the button action does not do anything .

IE11 Console shows the following error during the load of the page

  • Promise is undefined

I tried to do random stuff that got me nowhere.

I added <script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.3.5/bluebird.min.js"></script>

then I got "fetch is undefined"
So I added <script src="https://cdnjs.cloudflare.com/ajax/libs/fetch/2.0.3/fetch.js"></script>

and now I get-
undefined is not encodable in msgpack!

@springy76

This comment has been minimized.

Copy link

@springy76 springy76 commented Apr 16, 2019

Some doc/wiki page once mentioned you'll need polyfills. I tried some in the past without success.

@isc30

This comment has been minimized.

Copy link

@isc30 isc30 commented Apr 16, 2019

  1. get https://github.com/Daddoon/Blazor.Polyfill
  2. include it before blazor script tag
  3. profit
@springy76

This comment has been minimized.

Copy link

@springy76 springy76 commented Apr 16, 2019

I already tried that one. While it works for simple setups like the counter page, my stress test page (which I made for #6385) just never changes from "loading..." to final values: https://github.com/springy76/RazorComponentsProblems/blob/problem/ConnectionDiesWhenUsingAsyncOperations/WebApp/Components/Pages/Index.razor (and so does the real real world app which we're migrating to Razor components).

@isc30

This comment has been minimized.

Copy link

@isc30 isc30 commented Apr 16, 2019

That's an interesting edge case, I'll try to have a look and try to catch the errors there.
Does the console show any error?

@springy76

This comment has been minimized.

Copy link

@springy76 springy76 commented Apr 16, 2019

The console only shows timeout after 30s. But I have to revaluate because on my home machine the sample even crashes on Firefox earlier than expected. Maybe I hit the "MessagePack's ReadStringSlow looks broken" problem SteveSandersonMS has mentioned.

@isc30

This comment has been minimized.

Copy link

@isc30 isc30 commented Apr 16, 2019

yeah, that sounds more like a bug in the message queue than in the browser.

Answering the original question (ie11 polyfills), the mentioned library seems to work well on normal use cases

@mkArtakMSFT

This comment has been minimized.

Copy link
Member

@mkArtakMSFT mkArtakMSFT commented Apr 17, 2019

@javiercn can you please have a look at this and see what prevents us from supporting IE11? Thanks!

@mkArtakMSFT mkArtakMSFT added this to To do in Blazor via automation Apr 19, 2019
@mkArtakMSFT mkArtakMSFT added bug 1 - Ready and removed investigate labels Apr 19, 2019
@chrdlx

This comment has been minimized.

Copy link

@chrdlx chrdlx commented Apr 20, 2019

Hello! The https://github.com/Daddoon/Blazor.Polyfill solution doesn't work around here (IE11).
Do you know another alternative to try?
I've made an App using Blazor Server Side for the company I work for and found out it doesn't work in IE11. I hope they won't find out it doesn't work or I'll have to redo it again using Webforms (Yes, they still use Webforms for 95% of their apps).

@isc30

This comment has been minimized.

Copy link

@isc30 isc30 commented Apr 20, 2019

We need something to start working on, can you provide the console errors or some demo repository so we can debug it? Thanks

@chrdlx

This comment has been minimized.

Copy link

@chrdlx chrdlx commented Apr 20, 2019

We need something to start working on, can you provide the console errors or some demo repository so we can debug it? Thanks

The console doesn't show any error, if you want to replicate this, just create a new Server Side Blazor with the latest SDK (Preview 4) and run it.... the reactivity won't work. At least that's how I reproduce it.

@mkArtakMSFT mkArtakMSFT removed this from To do in Blazor Apr 22, 2019
@javiercn

This comment has been minimized.

Copy link
Member

@javiercn javiercn commented Apr 23, 2019

@danroth27 Can you update the issue based on our discussion?

@danroth27 danroth27 changed the title IE11 Razor Component IE11 support for server-side Blazor Apr 24, 2019
@SteveSandersonMS

This comment has been minimized.

Copy link
Member

@SteveSandersonMS SteveSandersonMS commented Apr 25, 2019

OK, I've investigated, and got it to work. But it involved making some changes inside blazor.server.js in addition to the polyfills.

I did:

  • Add core-js polyfills (covers most ES6 stuff): <script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.6.5/core.min.js"></script>
  • Add "fetch" polyfill (not part of core-js): <script src="https://polyfill.io/v3/polyfill.min.js?features=fetch"></script>
  • Fix document.baseURI [1]
  • Fix usage of Symbol [2]
  • Fix parseMarkup [3]

[1] Fix document.baseURI

document.baseURI just isn't set on IE11.

Workaround: In UriHelper.ts, change the getBaseURI logic so that instead of just returning document.baseURI, it includes some polyfill logic similar to this, but make sure you actually resolve it to an absolute URI like document.baseURI does.

[2] Fix usage of Symbol

In LogicalElement.ts, we call createSymbolOrFallback to instantiate a Symbol that's then used as a key into elements, e.g., someElement[theSymbol]. For whatever reason, this fails on IE11 with "stack out of range". It might even be a problem in one of the polyfill libraries I was using.

Workaround: change the createSymbolOrFallback logic so that, on IE11, it always uses the "fallback" code path (i.e., just returns a string).

[3] Fix parseMarkup

In BrowserRenderer.ts, we call parseMarkup to transform an HTML markup string into a DocumentFragment. This fails on IE11 because <template> elements lack a content property.

Workaround: replace return sharedTemplateElemForParsing.content; with:

    if (sharedTemplateElemForParsing.content) {
      return sharedTemplateElemForParsing.content;
    } else {
      const result = document.createDocumentFragment();
      while (sharedTemplateElemForParsing.firstChild) {
        result.appendChild(sharedTemplateElemForParsing.firstChild);
      }
      return result;
    }

Proposal

We should implement the three workarounds in our TypeScript code. Then it will be sufficient for people to add polyfills to make the whole thing work.

cc @danroth27

@chrdlx

This comment has been minimized.

Copy link

@chrdlx chrdlx commented Sep 24, 2019

@Daddoon I've found an issue with your Polyfill and the latest 3.0.0 Release, that makes Blazor fail when using URLs with parameters.

I attach the demo project as requested by @mkArtakMSFT

RouterIssue.zip

It's basically a default Blazor ServerSide template with the Counter component modified so it takes 1 parameter.
The issue appears when you use URLs with parameters, like this example:

image

This works fine in Chrome & Edge, but in IE11 the URLs that use a parameter don't work, showing this router error, like the URL doesn't exist.

If you browse the app first using a URL without parameters like https://localhost:44340/fetchdata, and then you click in the counter component link it seems to work because the connection is established. The problem appears when you browser directly the counter component, seems that blazor fails to establish a connection to the server.

Regards!

@Daddoon

This comment has been minimized.

Copy link

@Daddoon Daddoon commented Sep 24, 2019

Well, in my opinion it's surely a "bad" idea of my side.

I have done a fix on IE11 that take account what is the base start when a Blazor is not hosted on a simple base root.

However i have missed this type of scenario you are talking about, as i must reference the base path about the page path and not the app subpath.

In the meantime, before i take any action do it properly IF possible, if you take the original source code, you can revert to the previous implementation assuming launching Blazor from a simple base path. So this line:

document.baseURI = window.location.protocol + "//" + window.location.hostname + port + path;

Must be replaced with:

document.baseURI = window.location.protocol + "//" + window.location.hostname + port + "/";

Then it should work with the sample when calling your page with parameters.

I don't know if it is possible to get the real base path of the application URI from IE11 and Websocket if the given starting page is not the base application path. I have to do some test!

@danroth27

This comment has been minimized.

Copy link
Member

@danroth27 danroth27 commented Sep 24, 2019

We should implement the three workarounds in our TypeScript code. Then it will be sufficient for people to add polyfills to make the whole thing work.

@SteveSandersonMS @Daddoon Are these fixes still needed at this point? If yes, how is BlazorPolyfill working without these fixes?

@Daddoon

This comment has been minimized.

Copy link

@Daddoon Daddoon commented Sep 25, 2019

Hi @danroth27,

EDIT: Concerning your question, BlazorPolyfill is sufficient for running Blazor on IE11. I don't have made test about other old browsers like the one shipped with old Android versions.

TL;DR BlazorPolyfill should be sufficient

Concerning the tests, starting with the last stable Visual Studio 2019 release (16.3.29318.209):

Flat test, without Blazor.polyfill.js:

  • The page "Show" on IE11 but does not work. Actually, i think this is the server-side pre-rendering showing.
  • Clicking on other menu elements does still redirect to the correct page, but it seem to reload the page when doing it.
  • "Fetch data" sample view work
  • Clicking on "Click me" in "Counter page" does not work. No error thrown in the browser.

With Blazor.polyfill.js test:

  • The page does not reload when changing page => Normal Blazor behavior
  • Clicking on "Click me" in "Counter page" does work.

Without Blazor.polyfill.js but forcing window.Blazor.start():

  • Something new happen compared to the flat test, we have "Promise is undefined"

  • Adding Promise and other packaged Polyfills (sorry can't test individually rapidly) without document.baseURI defined return this error: "Unhandled promise rejection Error: undefined is not encodable in msgpack!" just after Blazor websocket connect.

  • Adding document.baseURI property defined is not enough. We have:

    • [2019-09-25T12:11:58.680Z] Error: There was an error applying batch 2.
    • Unhandled promise rejection Error: There is no browser renderer with ID 0.
    • [2019-09-25T12:11:58.754Z] Error: There was an unhandled exception on the current circuit, so this circuit will be terminated. For more details turn on detailed exceptions in 'CircuitOptions.DetailedErrors'.
    • [2019-09-25T12:11:58.756Z] Information: Connection disconnected.
  • Calling "Symbol.useSimple();" from core-js polyfill does fix the previous error. Also i tested that if i use it, but don't set document.baseURI, it still not working, the two fix are required.

Conclusion:

In actual release IE11 need:

  • Promise polyfill
  • core-js "Symbol.useSimple()"
  • document.baseURI defined
  • window.Blazor.start(); must be call explicitly

Maybe some other polyfills are required, i mean, i have tested individually a long time ago, but it was with the asmjs support, so there is maybe less requirement today.

But the 4 mentionned here seem still mandatory.

BlazorPolyfill does include theses requirements.

@Daddoon

This comment has been minimized.

Copy link

@Daddoon Daddoon commented Sep 25, 2019

@chrdlx I fixed the issue you mentionned. It should work right with root and not root path now on IE11.

See the release here.

@chrdlx

This comment has been minimized.

Copy link

@chrdlx chrdlx commented Sep 25, 2019

@Daddoon Beautiful !! Thank you very much!!

@mkArtakMSFT

This comment has been minimized.

Copy link
Member

@mkArtakMSFT mkArtakMSFT commented Oct 7, 2019

We will need to make sure this is covered too: #14784 as part of this work.

@mkArtakMSFT mkArtakMSFT added the cost: M label Oct 7, 2019
@Daddoon

This comment has been minimized.

Copy link

@Daddoon Daddoon commented Oct 7, 2019

@mkArtakMSFT According to what i see in the closed issue you mentionned, does this mean that Blazor will transpile Javascript code automatically at build time in the future, as a standard build subset ?

@SteveSandersonMS

This comment has been minimized.

Copy link
Member

@SteveSandersonMS SteveSandersonMS commented Oct 7, 2019

@Daddoon No, there is nothing about transpilation here.

@Daddoon

This comment has been minimized.

Copy link

@Daddoon Daddoon commented Oct 7, 2019

@SteveSandersonMS Sorry! So IMO, the referenced issue here (#14784) is just an usage of an ECMAScript version unsupported by IE11, by the original issuer. I think there is nothing to do. But i mean, that's why i thought we were maybe talking about transpilation.

Sorry again!

@SteveSandersonMS

This comment has been minimized.

Copy link
Member

@SteveSandersonMS SteveSandersonMS commented Oct 7, 2019

Oh I see! Yes you’re right. In the linked issue, the person was using the wrong syntax for IE11, so I agree there’s nothing for us to do with that.

@DanJBower

This comment has been minimized.

Copy link

@DanJBower DanJBower commented Oct 8, 2019

Yeah sorry about raising that issue. It was a mistake on my side. I appreciate the help in resolving that though

@MSBassSinger

This comment has been minimized.

Copy link

@MSBassSinger MSBassSinger commented Oct 26, 2019

I could use some help here. I created a Blazor serverside project (using the code as generated).

In _Host.cshtml I added:

	<script src="_framework/blazor.server.js"></script>
	<![if !IE]>
		<script src="blazor.polyfill.js" type="text/javascript">
			window.Blazor.Start();
		</script>
	<![endif]>

However, the [@OnClick="IncrementCount"] still does not work. What am I missing? I downloaded the blazor.polyfill.js from https://github.com/Daddoon/Blazor.Polyfill/releases/tag/3.0.0

Followup:
The counter now works in IE11, but I get this error on exit:

Unhandled exception at line 8, column 102493 in https://localhost:44350/_framework/blazor.server.js
0x800a01b6 - JavaScript runtime error: Object doesn't support property or method 'sendBeacon' occurred

My _Host.cshtml has this now:

	<script type="text/javascript" src="blazor.polyfill.js"></script>
	<script src="_framework/blazor.server.js"></script>
	<script>
		Blazor.start();
	</script>

How can I get rid of the 'sendBeacon' error?

@Daddoon

This comment has been minimized.

Copy link

@Daddoon Daddoon commented Oct 26, 2019

Please note that this polyfill is not something supported officially by Microsoft.

TL;DR I don't know yet how to avoid this error with Blazor.Polyfill

As stated on my repo:

For Blazor in Server-side mode

<script type="text/javascript" src="blazor.polyfill.min.js"></script>
<script src="_framework/blazor.server.js"></script>

And that's all. The polyfill should handle the Blazor.start() by itself.

For that sendBeacon error, i think this is something that my polyfill don't manage, and i have never tried to see on what this is related, and if i can do something on this error.

However, in the current state, the Blazor server-side app on IE11 work even with this error.
But thanks for your post, i will try to take a look, to see if i can integrate a polyfill for sendBeacon on my library.

EDIT: Opened an issue here: Daddoon/Blazor.Polyfill#12
I will come back soon here if i'm able to do a fix on that.

@MSBassSinger

This comment has been minimized.

Copy link

@MSBassSinger MSBassSinger commented Oct 26, 2019

Thanks. If I can ignore the error, that is fine for now.

I think one aspect MS fails to adequately recognize is that a LOT of government agencies and large companies are still standardized on IE 11. The cost to retrain and make Edge or another browser the standard is quite large, and not a high priority as long as line-of-business apps work on IE 11.

That means that internal development teams and consultants/contractors that want to start pushing our Blazor serverside apps, cannot do so if IE 11 is not fully supported on Blazor Serverside. The end result for MS is a delayed or no adoption of Blazor for wasm, and potentially the MS stack gets replaced by other wasm stacks that do support IE 11.

I and most users of IE 11 understand the browser is end-of-lifed and no longer supported for new functionality, like a wasm engine. But adoption of a modern browser is slowed by the cost for governments and large companies.

@Daddoon

This comment has been minimized.

Copy link

@Daddoon Daddoon commented Oct 26, 2019

I think MS was on it but mainly more focused about releasing the RTM of .NET Core 3.0 (Including Blazor server-side). And as polyfills can workaround the missing features, i think this is fine that they don't have priotized this.

Btw, Navigator.sendBeacon seem polyfillable as it's a browser feature and not something related to Blazor and that some polyfills exists like this one on NPM.

I'm taking a look on this right now as i have some time right now. I will release an update shortly if this work correctly on the sample.

I don't know where sendBeacon is used, but i think this may be used to sync some browser states when reconnecting for the current session but this is just an assumption.

@Daddoon

This comment has been minimized.

Copy link

@Daddoon Daddoon commented Oct 26, 2019

@MSBassSinger Done.

See the release here: https://github.com/Daddoon/Blazor.Polyfill/releases/tag/3.0.1

I don't see the error anymore since the polyfill included.

@MSBassSinger

This comment has been minimized.

Copy link

@MSBassSinger MSBassSinger commented Oct 26, 2019

Thanks. I am trying to prove to my employer (a consulting company that builds websites for a major federal agency) that it is safe to start shifting to Blazor serverside. Getting IE11 usable is the one big obstacle.

@Daddoon

This comment has been minimized.

Copy link

@Daddoon Daddoon commented Oct 26, 2019

Good luck with your Employer.

At least, with Blazor WASM, you can prove to your employer that Blazor is future proof, as if IE11 support drop one day, you will still be on the boat with a cutting edge technology in browser !

@MSBassSinger

This comment has been minimized.

Copy link

@MSBassSinger MSBassSinger commented Oct 26, 2019

Most assuredly! And your fix took care of it. As we say down here in the South, "I am cooking with gas!"

@springy76

This comment has been minimized.

Copy link

@springy76 springy76 commented Oct 28, 2019

@MSBassSinger

<![if !IE]>
		<script src="blazor.polyfill.js" type="text/javascript">
		</script>
	<![endif]>

To me this reads: "If not using InternetExploder then insert polyfill"

@willdean

This comment was marked as outdated.

Copy link

@willdean willdean commented Nov 20, 2019

Even with @Daddoon's polyfill (a great help, many thanks), we've had a problem with s/s Blazor with IE11 when the root component is hosted on a page which isn't at the root path /. (This is on 3.1 preview 3)

What happens is that SignalR tries to connect to http://localhost/our/path/_blazor, rather than http://localhost/_blazor which is what all the modern browsers do.

I gave up trying to work out why this was (TBH, I'm not 100% why it works on the modern browsers) and just added the following rewrite rule to Startup (before app.UseRouting():

app.UseRewriter(new RewriteOptions().AddRewrite("^.*_blazor(.*)", "/_blazor$1", true));

You might fancy a more sophisticated re-write rule, as this one could be a bit enthusiastic.

This might be useful to someone, if you get to a point where you're seeing 404 errors from the Blazor SignalR connection.

@Daddoon

This comment has been minimized.

Copy link

@Daddoon Daddoon commented Nov 20, 2019

Are you sure you are using a recent version of my polyfill ? I had fixed something about a similar issue some weeks ago.

Do you have a repro project with this bug ? If i can fix something about it, it would be better.

@willdean

This comment has been minimized.

Copy link

@willdean willdean commented Nov 20, 2019

@Daddoon - I'm not sure it's fixable in your polyfill, but if I can build a simple repro then I'll open an issue on your repro for you to look at.

@Daddoon

This comment has been minimized.

Copy link

@Daddoon Daddoon commented Nov 20, 2019

@willdean

This comment has been minimized.

Copy link

@willdean willdean commented Nov 20, 2019

@Daddoon Thank-you for pushing me to create a repro. This lead to the discovery that the problem was the base element being in the body of the page, not the head - i.e. entirely my fault... Thanks for the help.

@Daddoon

This comment has been minimized.

Copy link

@Daddoon Daddoon commented Nov 21, 2019

@willdean No problems, good to know it was a tag issue on your side. For a next update, maybe i should add a log error in the console mentionning the missing base tag, then if it's omitted it would be at least written in the browser console!

@Daddoon

This comment has been minimized.

Copy link

@Daddoon Daddoon commented Nov 21, 2019

I released a new version of the polyfill:

https://github.com/Daddoon/Blazor.Polyfill

  • Added an error in the console if the base tag is not found on IE
  • Re-added core-js in the library
  • Updated the documentation: You can now safely remove core-js external reference if you added it previously, but otherwise, it's recommended to only add the polyfill on a IE11 browser.

So to install, as stated in the updated doc:

<script type="text/javascript">
    if (/MSIE \d|Trident.*rv:/.test(navigator.userAgent)) {
        document.write('<script src="js/blazor.polyfill.min.js"><\/script>');
    }
</script>
<script src="_framework/blazor.server.js"></script>

...considering you have copied the file in a wwwroot/js folder.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.