【问题标题】:URLs requested via Http on the server must be absolute服务器上通过 Http 请求的 URL 必须是绝对的
【发布时间】:2018-11-06 06:49:32
【问题描述】:

我使用 angular2 创建了一个 angular 通用应用程序,我在其中请求 /category 服务。

this.hsService.getCategories(AppConstants.BASE_URL_GET_CATGORIES).subscribe(
  resp => {
    if (resp !== null) {
      console.log('response is not null');
    }else {
      console.log('response is null');
    }
  },
  err => {
    console.log('error');
    that.categories = that.Categories();
  }
);

但是我在错误下方得到了这个错误。但是不明白为什么?

ERROR 错误:通过服务器上的 Http 请求的 URL 必须是绝对的。 URL: /category at validateRequestUrl (D:\Myprojects\angular Universal\ciel\node_modules\@angular\platform-server\bundles\platform-server.umd.js:99:15 在新的 ZoneMacroTaskConnection (D:\Myprojects\angular 通用\ciel\node_modules\@angular\platform-server\bundles\platform-server.umd.js:226:9) 在 ZoneMacroTaskBackend.createConnection (D:\Myprojects\angular 通用\ciel\node_modules\@angular\platform-server\bundles\platform-server.umd.js:262:16) 在 httpRequest (D:\Myprojects\angular 通用\ciel\node_modules\@angular\http\bundles\http.umd.js:1833:20) 在 Http.request (D:\Myprojects\angular universal\ciel\node_modules\@angular\http\bundles\http.umd.js:1943:34) 在 Http.get (D:\Myprojects\angular universal\ciel\node_modules\@angular\http\bundles\http.umd.js:1957:21) 在 n.getCategories (D:\Myprojects\angular universal\ciel\dist-server\main.bundle.js:1:26301) 在 n.XV61.n.getCategories (D:\Myprojects\angular universal\ciel\dist-server\main.bundle.js:1:24428) 在 n.XV61.n.ngOnInit (D:\Myprojects\angular universal\ciel\dist-server\main.bundle.js:1:24346) 在 checkAndUpdateDirectiveInline (D:\Myprojects\angular universal\ciel\node_modules\@angular\core\bundles\core.umd.js:10875:19)

有人可以帮助我吗?

【问题讨论】:

  • 该 API 中的 Http 请求似乎必须是完整格式的 URL,例如 http://www.someDomain.com/somePath。您似乎正在尝试向/category 发出请求。显然你不能这样做。某处的某些代码必须包含协议和域。

标签: node.js angular angular-universal


【解决方案1】:

ERROR 错误:通过服务器上的 Http 请求的 URL 必须是绝对的。

看起来AppConstants.BASE_URL_GET_CATGORIESundefined 或无效的http URL。

我认为你需要注入原始 url 来创建绝对路径

export function createTranslateLoader(http: Http, @Inject('AppConstants.BASE_URL_GET_CATGORIES') originUrl: string) {
  return new TranslateHttpLoader(http, originUrl);
}

【讨论】:

    【解决方案2】:

    在服务器端渲染中,任何 HTTP 调用都需要绝对 URL。

    你可以

    1. 对 HTTP 请求使用绝对 URL
    2. 注入原始 URL 并添加到基本 URL 服务器端

    this 问题的答案中有多种解决方法可以执行选项 2

    我个人建议配置一个注入令牌,为您提供服务器的来源,并使用 HTTP 拦截器将其添加到基本 URL:

    添加HTTP拦截器类:

    import { Injectable, Inject, Optional } from '@angular/core';
    import { HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
    
    @Injectable()
    export class UniversalInterceptor implements HttpInterceptor {
    
      constructor(@Optional() @Inject('serverUrl') protected serverUrl: string) {}
    
      intercept(req: HttpRequest<any>, next: HttpHandler) {
    
        const serverReq = !this.serverUrl ? req : req.clone({
          url: `${this.serverUrl}${req.url}`
        });
    
        return next.handle(serverReq);
    
      }
    }
    

    将其添加到服务器端模块的 providers 数组中:

    providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: UniversalInterceptor,
      multi: true
    }
    

    在您的服务器端配置中(在此示例中表示),为令牌提供服务器的原始 URL:

    let protocol = 'http';
    if (process.env.NODE_ENV == 'production') {
       protocol = 'https'
    }
    
    app.engine('html', (_, options, callback) => {
      let engine = ngExpressEngine({
        bootstrap: AppServerModuleNgFactory,
        providers: [
          provideModuleMap(LAZY_MODULE_MAP),
          {
            provide: 'serverUrl',
            useValue: `${protocol}://${options.req.get('host')}`
          }
        ]
      });
    
      engine(_, options, callback)
    })
    

    【讨论】:

    • 感谢您的指出,协议可以是 http、https 或您的服务器使用的任何协议。编辑答案以包含初始化变量的一般方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-22
    • 2016-10-18
    • 1970-01-01
    • 1970-01-01
    • 2017-03-28
    • 1970-01-01
    相关资源
    最近更新 更多