Angular 2/4/5 - 动态设置基本href

时间:2016-06-30 02:14:11

标签: angular

我们有一个企业应用程序,它为客户端使用Angular 2。我们的每位客户都有自己独特的网址,例如https://our.app.com/customer-onehttps://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并且他们刷新页面或尝试直接点击该网址,则<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>

...

不幸的是,我们的想法很新鲜。任何帮助都会很棒。

14 个答案:

答案 0 :(得分:124)

这里标记的答案并没有解决我的问题,可能是不同的角度版本。我能够在终端/ shell中使用以下angular cli命令实现所需的结果:

ng build --base-href /myUrl/

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

这会将内置版本中的<base href="/">更改为<base href="/myUrl/"> ,这非常适合我们在开发和生产之间的环境变化。最好的部分是没有代码库需要使用此方法更改。

<小时/> 总结一下,将index.html基础href保留为:<base href="/">然后使用angular cli运行ng build --bh ./以使其成为相对路径,或者将./替换为您需要的任何内容。< p>

更新

如上例所示,如何从命令行执行此操作,以下是如何将其添加到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/",

official angular-cli文件涉及使用情况。

答案 1 :(得分:44)

这是我们最终做的事情。

将此添加到index.html。它应该是<head>部分

中的第一件事
<base href="/">
<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 { }

答案 2 :(得分:26)

基于你的(@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;
}

答案 3 :(得分:23)

在同一个域中构建多个应用时,我使用当前工作目录./

<base href="./">

在旁注中,我使用.htaccess来帮助我在页面重新加载时进行路由:

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

答案 4 :(得分:13)

answer简化现有@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 opaque标记提供值,则不必在index.html中指定基本标记。

答案 5 :(得分:10)

在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

答案 6 :(得分:8)

这在我的生产环境中工作正常

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

答案 7 :(得分:5)

如果您使用的是Angular CLI 6,则可以使用angular.json中的deployUrl / baseHref选项(项目&gt; xxx&gt;架构&gt;构建&gt;配置&gt;生产)。通过这种方式,您可以轻松地为每个项目指定baseUrl。

通过查看内置应用的index.html来检查您的设置是否正确。

答案 8 :(得分:1)

附加组件:如果您想要例如:/ users作为路由器的应用程序基础,/ public作为资产使用的基础

$ ng build -prod --base-href /users --deploy-url /public

答案 9 :(得分:1)

您可以使用以下命令在 app.module.ts 文件中动态设置基本 href:https://angular.io/api/common/APP_BASE_HREF

import {Component, NgModule} from '@angular/core';
import {APP_BASE_HREF} from '@angular/common';

@NgModule({
  providers: [{provide: APP_BASE_HREF, useValue: '/my/app'}]
})
class AppModule {}

答案 10 :(得分:0)

坦白说,你的案子对我来说很好!

我正在使用Angular 5。

<script type='text/javascript'>
    var base = window.location.href.substring(0, window.location.href.toLowerCase().indexOf('index.aspx'))
    document.write('<base href="' + base + '" />');
</script>

答案 11 :(得分:0)

有一个类似的问题,实际上我最终是在研究网络中是否存在某些文件。

probePath 是您要检查的文件的相对URL(如果您现在位于正确的位置,则为标记的一种),例如'assets / images / thisImageAlwaysExists.png'

<script type='text/javascript'>
  function configExists(url) {
    var req = new XMLHttpRequest();
    req.open('GET', url, false); 
    req.send();
    return req.status==200;
  }

  var probePath = '...(some file that must exist)...';
  var origin = document.location.origin;
  var pathSegments = document.location.pathname.split('/');

  var basePath = '/'
  var configFound = false;
  for (var i = 0; i < pathSegments.length; i++) {
    var segment = pathSegments[i];
    if (segment.length > 0) {
      basePath = basePath + segment + '/';
    }
    var fullPath = origin + basePath + probePath;
    configFound = configExists(fullPath);
    if (configFound) {
      break;
    }
  }

  document.write("<base href='" + (configFound ? basePath : '/') + "' />");
</script>

答案 12 :(得分:0)

在package.json中,将标志--base-href设置为相对路径:

"script": {
    "build": "ng build --base-href ./"
}

答案 13 :(得分:-2)

我刚刚改变了

  <base href="/">

对此:

  <base href="/something.html/">

不要忘记以/

结尾