2017-04-14 57 views
1

我需要获取我的Angular 2应用的完整基准网址(例如http://localhost:5000https://productionserver.com),以便我可以将它传递给应用上下文中的第三方服务。应用程序的位置取决于它是开发,各种分段/测试环境还是生产,并且我想动态检测它,因此我不需要维护硬编码列表。如何在Angular Universal中获得完整的基本URL(包括服务器,端口和协议)?

一个similar question已提出,在过去,但答案(即使用window.location.hostname或window.location.origin属性的某些版本),只有当angular2应用程序正在被浏览器呈现工作。

我想我的应用程序与Angular Universal一起工作,这意味着它需要在服务器端渲染,而不需要访问像window.location这样的DOM对象。

任何想法如何做到这一点?作为参考,使用asp.net核心作为后端(使用默认的dotnet新角模板)。

+0

有一个在通用ORIGIN_URL提供商,https://github.com/angular/universal/blob/2.x/modules /platform-node/tokens.ts#L6。我会建议检查它是否有效。任何方式,一个好习惯是提供包含主机名的环境变量/提供者。对于API调用,主机可能会有所不同,您可能迟早会做同样的事情。 – estus

+0

试着像'@Inject(ORIGIN_URL)@Optional()origin'那样注入它,并在服务器端调试它等于什么。 – estus

+0

感谢您的提示!我对Angular有点新鲜,所以原谅我,如果这是显而易见的,但你知道我可以检查ORIGIN_URL是否会给我我想要的吗?我尝试要求我的组件的构造函数是这样的: 构造函数(@Inject(ORIGIN_URL)private _origin) 但是我得到错误“无法解析所有HomeComponent参数”。我试着将它添加到我的ngModule装饰器的Providers数组中,但是这似乎也没有改变错误。也许有一些我不知道的语法细节? –

回答

1

感谢来自estus的帮助,我设法将一些有效的东西拼凑起来。

看起来大多数Angular Universal模板实际上都有服务器传递一个名为“originUrl”的区域参数,服务器呈现方法使用该参数来提供可以注入其他方法的ORIGIN_URL标记。我找不到任何关于此的文档,但您可以看到an example here

所以,如果你写这样的事情...

export function getBaseUrl() { 
    if (Zone.current.get("originUrl")) { 
     return Zone.current.get('originUrl'); 
    } else if (location) { 
     return location.origin; 
    } else { 
     return 'something went wrong!'; 
    } 
} 

你应该能够获取服务器和客户端上的完整源URL。

+0

'Zone.current.get(“originUrl”)在Angular 5中不适用于我。 – xuhcc

+0

@xuhcc - 您是否找到了解决方案? –

+0

@kris_IV - 是的,我添加了'request'提供程序作为@chintan adatiya建议。 – xuhcc

0

现在,我使用的server.ts ngExpressEngine

import { ngExpressEngine } from '@nguniversal/express-engine'; 

const {AppServerModuleNgFactory, LAZY_MODULE_MAP} = require('./dist/server/main.bundle'); 

    const {provideModuleMap} = require('@nguniversal/module-map-ngfactory-loader'); 

    app.engine('html', ngExpressEngine({ 
     bootstrap: AppServerModuleNgFactory, 
     providers: [ 
      provideModuleMap(LAZY_MODULE_MAP) 
     ] 
    })); 

此后,我可以在location.service.ts使用:

constructor(@Optional() @Inject(REQUEST) private request: any, 
      @Optional() @Inject(RESPONSE) private response: any, 
      @Inject(PLATFORM_ID) private platformId: Object) 
{ 
    if (isPlatformServer(this.platformId)) 
    { 
    console.log(this.request.get('host’)); // host on the server 
    } else 
    { 
    console.log(document.location.hostname); // host on the browser 
    } 
} 
+0

能否请您详细说明如何使用它?我想访问我的角码中的子域名主机 –

+0

这在我的情况下不起作用。 'this.request.get('host')'总是返回127.0.0.1:4000 –

4

我有位带有角度5和角度通用的工作代码

在server.ts中替换此

app.engine('html', (_, options, callback) => { 
    let engine = ngExpressEngine({ 
     bootstrap: AppServerModuleNgFactory, 
     providers: [ 
      { provide: 'request', useFactory:() => options.req, deps: [] }, 
      provideModuleMap(LAZY_MODULE_MAP) 
     ] 
    }); 
    engine(_, options, callback); 
}); 

及其在角边你可以用下面的代码获取主机

export class AppComponent { 
    constructor(
     private injector: Injector, 
     @Inject(PLATFORM_ID) private platformId: Object 
    ) { 
     console.log('hi, we\'re here!'); 
     if (isPlatformServer(this.platformId)) { 
      let req = this.injector.get('request'); 
      console.log("locales from crawlers: " + req.headers["accept-language"]); 
      console.log("host: " + req.get('host')); 
      console.log("headers: ", req.headers); 
     } else { 
      console.log('we\'re rendering from the browser, there is no request object.'); 
     } 
    } 
} 
+0

当我在本地运行它时,它工作正常,但在服务器上它给出了没有提供程序请求的错误! 。有没有解决方案?我正在研究Angular 4 – twitch

相关问题