Get domain from Angular 5 Universal always return

2019-02-27 15:45发布

问题:

I have a problem with Server Side Rendering of Angular 5 apps. I need domain to create proper link (app is used in different environments and it's bad idea to create few packages to each endpoint).

So I try to use option from stack, but always i get 127.0.0.1:4000 as a domain/host. I think that the best option should be:

server.ts

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

And in app.component.ts:

   constructor(@Inject(PLATFORM_ID) private platformId,
                private injector: Injector) {

        if (isPlatformServer(this.platformId)) {
            let req = this.injector.get('request');
            console.log("host: " + req.get('host'));
        } else {
            console.log('we\'re rendering from the browser, there is no request object.');
        }
    }

I check also object option from NodeJS -> it doesn't has any information about a domain. host is defined there as 127.0.0.1:4000. I doesn't has any idea how can I get it from NodeJS. Can you help or give small tips?

Maybe my fault is that I has wrong Nginx configuration?

server {
    listen 80;
    listen [::]:80;
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name mock.test.com;

    ssl_certificate /home/xxx/Projects/xsw/cert/certificate.chained.crt;
    ssl_certificate_key /home/xxx/Projects/xsw/cert/key.prv;

    root /home/xxx/Projects/xsw/;
    index index.html;

    location / {
        proxy_pass http://127.0.0.1:4202;
    }

}

回答1:

I lose today about 10 hours but finally I found a solution. My problem was connected with nginx configuration.

When I use:

location / {
    proxy_pass http://127.0.0.1:4000;
}

Nginx change host in request into 127.0.0.1:4000. So a solution for this is edit nginx proxy into:

location / {
    proxy_pass http://127.0.0.1:4000;
    proxy_set_header Host example.com;
    proxy_set_header HTTPS on;
}

I doesn't change anything in my express node.js server:

server.ts

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

And in my app.component.ts I use this config:

   private domain: string;

   constructor(@Optional() @Inject(REQUEST) private request: any,
               @Inject(PLATFORM_ID) private platformId,
               private injector: Injector) {

        if (isPlatformServer(this.platformId)) {
            if (this.request.get('https')) {
                this.domain = 'https://' + this.request.get('host');
            } else {
                this.domain = 'http://' + this.request.get('host');
            }
        } else {
            this.domain = document.location.protocol + '//' + document.location.hostname;
        }
    }

To create this answer I use another answer from StackOverflow: https://stackoverflow.com/a/47434417/2972087 And part of Nginx Docs: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header