[angular] Angular 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="https://stackoverflow.com/' + base + '" />');
  </script>

...

불행히도 우리는 아이디어가 새롭습니다. 어떤 도움이라도 놀랄 것입니다.



답변

여기에 표시된 답변으로는 내 문제가 해결되지 않았으며 다른 각도 버전 일 수 있습니다. angular cli터미널 / 셸에서 다음 명령을 사용하여 원하는 결과를 얻을 수있었습니다 .

ng build --base-href /myUrl/

ng build --bh /myUrl/ 또는 ng build --prod --bh /myUrl/

이것은 변경 <base href="https://stackoverflow.com/"><base href="https://stackoverflow.com/myUrl/">에서 유일한 내장 버전 개발과 생산 사이의 환경에서 우리의 변화에 대한 완벽했다. 가장 좋은 점은이 방법을 사용하여 코드베이스를 변경할 필요가 없다는 것입니다.


요약하려면 index.html기본 href를 <base href="https://stackoverflow.com/">다음 ng build --bh ./과 같이 두십시오 . 그런 다음 angular cli로 실행 하여 상대 경로로 만들거나 ./필요한 것으로 대체하십시오 .


최신 정보:

위의 예에서 명령 줄에서 수행하는 방법을 보여 주듯이 angular.json 구성 파일에 추가하는 방법은 다음과 같습니다.

이것은 모두 ng serving지역 개발을 위해 사용될 것입니다

"architect": {
    "build": {
      "builder": "@angular-devkit/build-angular:browser",
      "options": {
        "baseHref": "/testurl/",

이것은 prod와 같은 구성 빌드에 특정한 구성입니다.

"configurations": {
   "Prod": {
     "fileReplacements": [
        {
          "replace": src/environments/environment.ts",
          "with": src/environments/environment.prod.ts"
        }
      ],
      "baseHref": "./productionurl/",

사용법에 관한 공식 angular-cli 문서.


답변

여기에 우리가 한 일이 있습니다.

이것을 index.html에 추가하십시오. <head>섹션 에서 가장 먼저해야합니다.

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

그런 다음 app.module.ts파일 에서 다음 { 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) 답변을 바탕으로 조금 더 리팩토링 할 수 있었으므로 .NET에서 함수를 해킹 할 필요가 없습니다 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]


답변

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

APP_BASE_HREF 불투명 토큰에 대한 값을 제공하는 경우 index.html에서 기본 태그를 지정할 필요가 없습니다.


답변

이것은 prod 환경에서 잘 작동합니다.

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


답변

angular4에서는 .angular-cli.json 앱에서 baseHref를 구성 할 수도 있습니다.

.angular-cli.json에서

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

index.html의 기본 href가 MY_APP_BASE_HREF_1로 업데이트됩니다.

ng build --app myapp1