Angular 2.错误:加载块失败

时间:2017-05-17 20:15:15

标签: javascript angular typescript

使用带有延迟加载模块的角度2,我可以从服务器

接收(例如)401 HTTP代码
  

bootstrap 0b40fee ...:101 GET http://localhost:8082/2.chunk.js

Error: Loading chunk 2 failed.
at HTMLScriptElement.onScriptComplete (bootstrap 0b40fee…:91)
at HTMLScriptElement.wrapFn (zone.js:1032)
at ZoneDelegate.invokeTask (zone.js:414)
at Object.onInvokeTask (core.es5.js:4119)
at ZoneDelegate.invokeTask (zone.js:413)
at Zone.runTask (zone.js:181)
at HTMLScriptElement.ZoneTask.invoke (zone.js:476)

如何处理此错误?

8 个答案:

答案 0 :(得分:3)

我遇到了同样的问题,所以我进行了调查。我找到了解决方案。当我重新部署到另一台服务器并且块有[哈希]时,这发生在我身上。

你可以在这样的捕获中捕获错误:

ngOnInit() {
    if (!this.previousRouterErrorHandler) {
        this.previousRouterErrorHandler = this.router.errorHandler;
        let that = this;
        this.router.errorHandler = function (err: any) {
            // Handle here. err.message == "Loading chunk chunk-name failed."

            return that.previousRouterErrorHandler.apply(that.previousRouterErrorHandler, arguments);
        };
    }
}

或直接在导航的链接

click() {
    this.router.navigate(['/lazy-route'])
        .catch(err => {
            // Handle here
        });
}

答案 1 :(得分:3)

检查my answer以获得详细信息

  • 绕过此块失败的解决方法失败错误=>如果使用global error handler发生块失败错误,则以编程方式强制应用重新加载。

import { ErrorHandler } from '@angular/core';

@Injectable()
export class GlobalErrorHandler implements ErrorHandler {

  handleError(error: any): void {
   const chunkFailedMessage = /Loading chunk [\d]+ failed/;

    if (chunkFailedMessage.test(err.message)) {
      window.location.reload();
    }
  }
}
  • 在根模块中提供它来更改应用程序中的默认行为,因此,我们使用自定义GlobalErrorHandler类来代替使用默认的ErrorHandler类。

@NgModule({   
  providers: [{provide: ErrorHandler, useClass: GlobalErrorHandler}]
})

答案 2 :(得分:2)

这是我的解决方案。我将此服务作为单例注入到我的应用程序/核心模块中。

它等待来自路由器的NavigationError实例,检查它们是否为ChunkLoadError,然后重定向到用户想要去的地方。

// Angular
import { Injectable, OnDestroy } from '@angular/core';
import { Router, NavigationError } from '@angular/router';
// Rxjs
import { Subscription } from 'rxjs';
import { filter } from 'rxjs/operators';

@Injectable()
export class ChunkErrorHandler implements OnDestroy {
  private subscription: Subscription;

  constructor(router: Router) {
    this.subscription = router.events
      .pipe(filter(event => event instanceof NavigationError))
      .subscribe(event => {
        this.handleRouterErrors(event as NavigationError);
      });
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }

  private handleRouterErrors(event: NavigationError) {
    if (event.error.name === 'ChunkLoadError') {
      window.location.href = `${window.location.origin}${event.url}`;
    }
  }
}

答案 3 :(得分:1)

部署新代码时会发生这种情况。保存文件和哈希的manifest.js不会在不刷新的情况下进行更新,并且在加载块时显然会使用manifest.js中的旧哈希。

因此,在捕获错误的同时,我们可以使用给定的URL强制重新加载:-

click() {
      this.router.navigate(['/lazy-route'])
           .catch(err => {
              // Handle here
              // reload with given route
              // window.location.pathname('/lazy-route');

              // OR
              // reset existing route(containing query params) with given route and force reload
               window.history.pushState({}, document.title, '/lazy-route' );
               window.location.reload();
           });
 }

答案 4 :(得分:0)

与区块相关的错误可能由任何环境或路由相关的问题引起,从而使它们难以揭穿。

在我的情况下,我的PWA中移动的数据量太多,无法由角度路由器处理。它淹没了js块获取器的标头,因此引发了bad_request错误。

我建议您检查一下这些网络调用(诸如http://localhost:xxxx/158.js之类的chunks.js的获取器)以查找标头中的任何异常,并重构当前开发环境中的粗略内容,因为这是调查黑名单的真正时间。错误的来源。

希望会有所帮助

答案 5 :(得分:0)

就我而言,我将文件放入S3存储桶中。我一直收到此错误,因为它一起调用了错误的文件名并返回了html错误响应。

在某个时候,我让IT团队知道发生了什么事。他们就像,让我们使CloudFront上的缓存无效...什么?!是的我们来做...

故事的寓意,如果您一直在网络上寻找此错误的答案,但找不到答案,请与IT团队或任何地方联系,以确保可能会缓存index.html文件。

答案 6 :(得分:0)

检查渔获存储,我想服务人员在渔获存储中保存了一些东西

答案 7 :(得分:-2)

这可能意味着未处理的异常。你必须以任何你想要的方式处理来自服务器的错误响应(4xx,5xx状态代码):在某处显示错误消息,重定向到某个页面,做任何事情但不要让它处理不当。

例如:

return this.http.get(requestDetails)
          .map(res => res.json())
          .catch(err => {
console.log('server error:', err)
Observable.throw(err);
});