Угловой 2 / 4 / 5 - установить базовую href динамически


у нас есть корпоративное приложение, которое использует Angular 2 для клиента. Каждый из наших клиентов имеет свой собственный уникальный url, например:https://our.app.com/customer-one и https://our.app.com/customer-two. В настоящее время мы можем установить <base href...> динамически, используя document.location. Так что пользователь попадает https://our.app.com/customer-two и <base href...> на /customer-two...отлично!

проблема в том, что пользователь, например, находится в https://our.app.com/customer-two/another-page и они обновляют страницу или пытаются попасть в этот url напрямую,<base href...> на /customer-two/another-page и ресурсы не могут быть найдено.

мы пробовали следующее безрезультатно:

<!doctype html>
<html>

<head>
  <script type='text/javascript'>
    var base = document.location.pathname.split('/')[1];
    document.write('<base href="/' + base + '" />');
  </script>

...

к сожалению, мы только что из идей. Любая помощь была бы удивительной.

8 66

8 ответов:

отмеченный ответ здесь не решил мою проблему, возможно, разные угловые версии. Мне удалось добиться желаемого результата с помощью следующих angular cli команда в терминале / оболочке:

ng build --base-href /myUrl/

ng build --bh /myUrl/ или ng build --prod --bh /myUrl/

это меняет <base href="/"> до <base href="/myUrl/"> на только встроенная версия которое было совершенно для нашего изменения в окружающей среде между развитием и продукцией. Лучшая часть была без кода база требует изменения используя этот метод.


Подводя итог, оставьте свой index.html база href as: выполнить ng build --bh ./ с угловым cli, чтобы сделать его относительным путем, или заменить ./ С тем, что вам требуется.

The официальныйangular-cli документация, относящаяся к использованию.

вот что мы делали.

добавить в индекс.формат html. Это должно быть первым делом в <head> раздел

<base href="/">
<script>
  (function() {
    window['_app_base'] = '/' + window.location.pathname.split('/')[1];
  })();
</script>

затем в добавьте { provide: APP_BASE_HREF, useValue: window['_app_base'] || '/' } к списку провайдеров, вот так:

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 { }

основываясь на вашем (@sharpmachine) ответе, я смог немного рефакторинговать его, так что нам не нужно взломать функцию в 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 { }

и ./shared/common-functions.util.ts содержит:

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;
}

Я использую текущий рабочий каталог ./ при создании нескольких приложений с одного домена:

<base href="./">

на боковой ноте, я использую .htaccess чтобы помочь с моей маршрутизацией на странице перезагрузки:

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

упрощение существующего ответ by @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 { }

вам не нужно указывать базовый тег в индексе.html, если вы предоставляете значение для непрозрачного токена APP_BASE_HREF.

в angular4, вы также можете настроить baseHref В.угловой-кли.приложения json.

in .угловой-кли.json

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

это обновит базовый href в индексе.html в MY_APP_BASE_HREF_1

ng build --app myapp1

эта работа отлично подходит для меня в среде prod

<base href="/" id="baseHref">
<script>
  (function() {
    document.getElementById('baseHref').href = '/' + window.location.pathname.split('/')[1] + "/";
  })();
</script>

Если вы используете угловой CLI 6, Вы можете использовать параметры deployUrl/baseHref в angular.json (проекты > xxx > архитектор > сборка > конфигурации > производство). Таким образом, вы можете легко указать на базовый проект.

проверьте правильность настроек, посмотрев на индекс.html встроенного приложения.