Angular 2/4/5 – Establecer href base dinámicamente

Tenemos una aplicación empresarial que usa Angular 2 para el cliente. Cada uno de nuestros clientes tiene su propia URL única, por ejemplo: https://our.app.com/customer-one y https://our.app.com/customer-two . Actualmente podemos establecer dinámicamente usando document.location . De modo que el usuario acceda a https://our.app.com/customer-two y se establece en /customer-two … ¡perfecto!

El problema es si el usuario está, por ejemplo, en https://our.app.com/customer-two/another-page y ellos actualizan la página o intentan acceder a esa URL directamente, la se establece a /customer-two/another-page y los recursos no pueden ser encontrados.

Hemos intentado lo siguiente en vano:

     var base = document.location.pathname.split('/')[1]; document.write('');  ... 

Lamentablemente, estamos frescos de ideas. Cualquier ayuda sería increíble.

La respuesta marcada aquí no resolvió mi problema, posiblemente diferentes versiones angulares. Pude lograr el resultado deseado con el siguiente comando angular cli en terminal / shell:

ng build --base-href /myUrl/

ng build --bh /myUrl/ o ng build --prod --bh /myUrl/

Esto cambia a en la versión construida, que fue perfecta para nuestro cambio de entorno entre desarrollo y producción. La mejor parte es que no hay una base de código que requiera cambiar usando este método.


Para resumir, deje index.html base href como: luego ejecute ng build --bh ./ con angular cli para convertirlo en una ruta relativa, o reemplace el ./ con lo que necesite.

La documentación oficial de angular-cli referente al uso.

Esto es lo que terminamos haciendo.

Agregue esto a index.html. Debería ser lo primero en la sección

   

Luego, en el archivo app.module.ts , agregue { provide: APP_BASE_HREF, useValue: window['_app_base'] || '/' } { provide: APP_BASE_HREF, useValue: window['_app_base'] || '/' } a la lista de proveedores, así:

 import { NgModule, enableProdMode, provide } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { APP_BASE_HREF, Location } from '@angular/common'; import { AppComponent, routing, appRoutingProviders, environment } from './'; if (environment.production) { enableProdMode(); } @NgModule({ declarations: [AppComponent], imports: [ BrowserModule, HttpModule, routing], bootstrap: [AppComponent], providers: [ appRoutingProviders, { provide: APP_BASE_HREF, useValue: window['_app_base'] || '/' }, ] }) export class AppModule { } 

En función de su respuesta (@sharpmachine), pude refactorizarlo un poco más, para que no tengamos que hackear una función en index.html .

 import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { APP_BASE_HREF, Location } from '@angular/common'; import { AppComponent } from './'; import { getBaseLocation } from './shared/common-functions.util'; @NgModule({ declarations: [AppComponent], imports: [ BrowserModule, HttpModule, ], bootstrap: [AppComponent], providers: [ appRoutingProviders, { provide: APP_BASE_HREF, useFactory: getBaseLocation }, ] }) export class AppModule { } 

Y, ./shared/common-functions.util.ts contiene:

 export function getBaseLocation() { let paths: string[] = location.pathname.split('/').splice(1, 1); let basePath: string = (paths && paths[0]) || 'my-account'; // Default: my-account return '/' + basePath; } 

Utilizo el directorio de trabajo actual ./ cuando construyo varias aplicaciones fuera del mismo dominio:

  

En una nota lateral, uso .htaccess para ayudar con mi enrutamiento en la recarga de la página:

 RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteRule .* index.html [L] 

Simplificación de la respuesta existente por @sharpmachine .

 import { APP_BASE_HREF } from '@angular/common'; import { NgModule } from '@angular/core'; @NgModule({ providers: [ { provide: APP_BASE_HREF, useValue: '/' + (window.location.pathname.split('/')[1] || '') } ] }) export class AppModule { } 

No es necesario que especifique una etiqueta base en index.html, si proporciona valor para el token opaque APP_BASE_HREF.

En angular4, también puede configurar la baseHref en aplicaciones .angular-cli.json.

en .angular-cli.json

 { .... "apps": [ { "name": "myapp1" "baseHref" : "MY_APP_BASE_HREF_1" }, { "name": "myapp2" "baseHref" : "MY_APP_BASE_HREF_2" }, ], } 

esto actualizará href base en index.html a MY_APP_BASE_HREF_1

 ng build --app myapp1 

Esto funciona bien para mí en el entorno prod

   

Si está usando Angular CLI 6, puede usar las opciones deployUrl / baseHref en angular.json (projects> xxx> architect> build> configurations> production). De esta forma, puede especificar fácilmente la baseUrl por proyecto.

Verifique que su configuración sea correcta mirando el index.html de la aplicación creada.