Angular 2 / 4 / 5 在 IE11 中无法正常工作。

134

我正在尝试弄清楚为什么我的Angular 2应用在IE 11中运行时一直显示“加载中...”。

按照别人的建议,我在chrome和IE 11上尝试了一个在stackoverflow上发布的plunker。在Chrome上运行良好,但在IE 11上失败。同样的错误,卡在“加载中...”上。

plunker链接: https://plnkr.co/edit/6zVFbrH5yohwc714gBbk?p=preview

<!DOCTYPE html>
<html>
  <head>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <title>Router Sample</title>
    <link rel="stylesheet" href="style.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.34.2/es6-shim.min.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.1/angular2-polyfills.js"></script>
    <script src="https://code.angularjs.org/tools/system.js"></script>
    <script src="https://code.angularjs.org/tools/typescript.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.1/Rx.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.1/angular2.dev.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.1/http.dev.js"></script>
    <script>
      System.config({
        transpiler: 'typescript', 
        typescriptOptions: { emitDecoratorMetadata: true }, 
        packages: {'src': {defaultExtension: 'ts'}} 
      });
      System.import('src/boot')
            .then(null, console.error.bind(console));
    </script>
  </head>

  <body>
    <my-app>loading...</my-app>
  </body>

</html>

有人知道为什么IE 11不能运行Angular 2应用程序吗?

谢谢!


现在的答案是使用2.0.0-beta.0版本。 - Pat Bone Crusher Laplante
22个回答

190

默认情况下,angular 的最新版本仅为常青浏览器进行了设置...

当前设置是针对所谓的“常青”浏览器;自动更新自己的浏览器的最新版本。这包括桌面版 Safari >= 10、Chrome >= 55(包括 Opera)、Edge >= 13,以及移动端的 iOS 10 和 Chrome。
尽管未被提及,但也适用于 Firefox。

有关浏览器支持的更多信息以及推荐特定浏览器的 polyfills 列表,请参见此处:https://angular.io/guide/browser-support#polyfill-libs


这意味着您需要手动启用正确的 polyfills 才能使 Angular 在 IE11 及以下版本中正常工作。


要实现这一点,请进入 polyfills.ts(默认位于 src 文件夹中),然后只需 取消注释以下导入即可:

/***************************************************************************************************
 * BROWSER POLYFILLS
 */

/** IE9, IE10 and IE11 requires all of the following polyfills. **/
 import 'core-js/es6/symbol';
 import 'core-js/es6/object';
 import 'core-js/es6/function';
 import 'core-js/es6/parse-int';
 import 'core-js/es6/parse-float';
 import 'core-js/es6/number';
 import 'core-js/es6/math';
 import 'core-js/es6/string';
 import 'core-js/es6/date';
 import 'core-js/es6/array';
 import 'core-js/es6/regexp';
 import 'core-js/es6/map';
 import 'core-js/es6/set';

请注意,评论文字确实在文件中,因此很容易找到。

如果您仍然遇到问题,可以像@MikeDub建议的那样,在tsconfig.json中将target属性降级为es5。这样就会将任何es6定义的编译输出更改为es5定义。例如,fat arrow函数(()=>{})将被编译为匿名函数(function(){})。您可以在这里找到支持es6的浏览器列表。


• 在评论区,@jackOfAll问我是否会在用户使用不需要IE11 polyfill的evergreen浏览器时加载它们。答案是,是的!包含IE11 polyfills将使您的polyfill文件从~162KB增加到~258KB,截至2017年8月8日。我已尽力解决此问题,但目前看来不可能。

• 如果您在IE10及以下版本中遇到错误,请进入package.json并将webpack-dev-server降级至特定版本2.7.1。此版本以上的版本不再支持“旧”的IE版本。


3
即使我已经取消注释IE的polyfill,我的Angular 5项目仍然有相同的错误,在IE浏览器中仍然无法工作。太奇怪了... - Abby
3
我会尝试翻译您提供的内容: “@dudewad,我正在尝试创建两个单独的打包文件,其中一个专门为IE11设计,然后将该打包文件放在IE条件注释中,这将防止它在Chrome中运行。” - Zze
1
@Zze 嗯,你做得非常周全。不错,我喜欢这样。 - dudewad
1
@Zze 条件注释在IE10中被移除了,它们只支持IE5-9。因此,除非你特别进行用户代理嗅探并在运行时将你的捆绑包添加到页面中,否则你的IE捆绑包不会加载到IE10+上。 - bmcminn
您可以按照此处的描述将IE polyfills分离,以便它们不会在其他浏览器中加载:https://izifortune.com/angular-polyfill-strategies/ - Chris
显示剩余8条评论

23

我遇到了完全相同的问题,而且没有任何解决方案对我有用。相反,在(主页).html文件的<head>标签下添加以下代码解决了我的问题。

我遇到了完全相同的问题,而且没有任何解决方案对我有用。相反,在(主页).html文件的<head>标签下添加以下行可以解决这个问题。

<meta http-equiv="X-UA-Compatible" content="IE=edge" />

考虑到来自此SO https://dev59.com/Tl8d5IYBdhLWcg3w3FZk 的信息,建议使用X-UA-Compatible似乎已经失效。 - Lubiluk

20
我今天遇到了这个问题。我在GitHub上找到了一个解决方案,它不需要去更高版本的beta。
将以下脚本添加到您的html中:

我今天遇到了这个问题。我在GitHub上找到了一个解决方案,它不需要去更高版本的beta。

将以下脚本添加到您的html中:

<script src="node_modules/angular2/es6/dev/src/testing/shims_for_IE.js"></script>

这解决了我的问题。如需更多详情,请在此处关注 github 问题: https://github.com/angular/angular/issues/7144


3
这个解决方案对我没用 :( ... [在运行于IE上的VS2015项目中] - Ceylan Mumun Kocabaş

12

截至2017年2月

使用Angular-Cli项目,polyfills.ts文件中的所有行已取消注释,因此所有polyfills已经在被使用。

我在这里找到了解决办法。

总结上面的链接,IE不支持lambda箭头/脂肪箭头函数,这是ES6的一个功能。(如果polyfills.ts对您无效)。

解决方案:您需要将其目标设置为ES5,以便在任何IE版本中运行,仅微软的新Edge浏览器引入了此功能。

这可以在src/tsconfig.json中找到:

"outDir": "../dist/out-tsc",
"sourceMap": true,
"target": "es5",

这个答案非常误导人。Polyfills是使IE 9及以上版本与ES6标准兼容的脚本,如此处所示:https://angular.io/docs/ts/latest/guide/browser-support.html。因此,浏览器是否原生支持箭头函数并不重要,Polyfills完全可以解决这个问题。 - Zze
8
在我的情况下,我所经历的是如何会产生误导?尽管填充已被取消注释,但它们并没有解决我在IE11中遇到的问题。我认为这并不值得被踩。 - MikeDub
重新阅读后,我明白你想表达什么,但目前的措辞听起来好像你必须手动更改所有使用fat arrow的.ts文件为anon funcs。我认为你应该从链接中剪切一个引用,说明如果更改ecma script目标,则编译器输出会有所不同,从而缓解了这个问题。 - Zze
5
此外,我已经在我的tsconfig中将目标设置为es5,但仍然存在问题。 - gh0st
1
@MikeDub 我尝试使用你的解决方案,但在IE11上无效。你能提供更好的方法吗? - Prasanna

11

您需要调整polyfills.ts文件以适应目标浏览器,方法是取消注释相应的部分。

/** IE9, IE10 and IE11 requires all of the following polyfills. **/
import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/array';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/weak-map';
import 'core-js/es6/set';

1
这太棒了。谢谢你。 - AtLeastTheresToast

10

我使用iexplorer 11和Angular 2,通过两个步骤解决了上述所有问题:

在index.html中添加:

<meta http-equiv="X-UA-Compatible" content="IE=edge" />

在 src\polyfills.ts 中取消注释:

/** IE9, IE10 and IE11 requires all of the following polyfills. **/
import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/array';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/weak-map';
import 'core-js/es6/set';

1
是的,这对于IE11有效,但对于IE10无效:ERROR Error: Uncaught (in promise): TypeError: Object doesn't support property or method 'setPrototypeOf' at EmptyError (http://localhost:4200/vendor.js:102653:9) - Junior Mayhé

10
  1. 在polyfill.ts文件中取消注释一些导入。

/** IE9, IE10 and IE11 requires all of the following polyfills. **/
import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/array';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/weak-map';
import 'core-js/es6/set';

安装npm包 注意评论中有一些npm安装命令。如果您使用的是早期版本的Angular CLI,则可能还有第三个命令。对于Angular CLI 7、6和1.7版本,您需要运行:

npm install --save classlist.js

npm install --save web-animations-js

现在打开IE并渲染应用程序并进行检查 :)


9
EDIT 2018/05/15: 这可以通过元标签实现,请在index.html中添加该标签,忽略本帖。
这并不是完整的答案(有关技术解答,请参阅@Zze上面的答案),但还有一个重要的步骤需要添加:
兼容模式
即使适当的polyfills已经安装了,使用IE11仍然存在运行Angular 2+应用程序的问题。 如果您正在使用内部网络主机运行站点(例如,如果您正在测试它在http://localhost或另一个映射的本地域名),则必须进入兼容性视图设置并取消选中“在兼容性视图中显示内部网站”, 因为IE11的兼容性视图破坏了ES5 polyfills中包含的一些约定。 enter image description here

1
如果您遵循此解决方案,则必须在运行应用程序的所有客户端上执行此操作。将特殊标记添加到您的HTML文件中,可以强制浏览器运行最新版本,而不是兼容模式。 请参考以下答案查找标记:https://dev59.com/uVsW5IYBdhLWcg3wTlu8#47777695 - Poly
2
根据我的经验,如果您的应用程序在内部网络主机上提供服务,则使用此元标记不会覆盖IE 11的默认设置为“在兼容性视图中显示内部网络站点”。内部网络应用程序的用户仍然需要手动取消选中此选项,这不是理想的情况。我目前正在寻找解决方法 - 可能是编译为ES5而不是ES6。 - Kyle Vassella

8
截至2017年9月(node版本=v6.11.3,npm版本=3.10.10),以下是我使用的方法(感谢@Zze):
编辑polyfills.ts并取消对IE11必需的导入的注释。
更准确地说,在src文件夹下默认情况下编辑polyfills.ts,只需取消所有适用于IE11的行的注释(文件内的注释解释了运行IE11所需的精确导入)。
小心警告:当取消classlist.jsweb-animations-js的注释时,请注意。这些已注释的行各有一个特定的注释:在取消注释或处理polyfills.ts之前,必须运行相关的npm命令,否则会导致错误发生。
作为解释,polyfills是实现在不支持它的Web浏览器上的功能的代码片段。这就是为什么在默认polyfills.ts配置中只激活了一个最小的导入集合(因为它针对的是“常绿”浏览器;自动更新其自身的浏览器的最新版本)。

6

我有一个Angular4应用程序,即使对我来说,在IE11浏览器中也无法正常工作。 我已经进行了以下更改,现在它可以正常工作。

只需在index.html文件中添加以下代码:

<meta http-equiv="X-UA-Compatible" content="IE=edge" />

只需要取消注释下面的这些行,从polyfills.ts文件中:

import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/array';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/weak-map';
import 'core-js/es6/set';

这两个步骤可以解决您的问题,请告诉我是否有任何疑问。谢谢!

我已经取消了这两个部分的注释,但它仍然无法工作,你有另一个解决方案吗? - Menna Ramadan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接