角2 +-动态设置基础 href

我们有一个企业应用程序,使用角度2的客户端。我们的每个客户都有自己独特的网址,例如: https://our.app.com/customer-onehttps://our.app.com/customer-two。目前,我们能够使用 document.location动态设置 <base href...>。所以用户点击 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>


...

不幸的是,我们已经没有主意了,任何帮助都是很棒的。

203691 次浏览

我们最后是这么做的。

将它添加到 index.html

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

当我在同一个域名下开发几个应用时,我使用的是当前的工作目录 ./:

<base href="./">

另外,我使用 .htaccess来协助我重新加载页面时的路由:

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

基于你(@Sharp machine)的回答,我可以进一步重构它,这样我们就不必在 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;
}

这里有标记的答案并没有解决我的问题,可能是不同的角度版本。我能够使用以下终端/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="/">,然后运行 ng build --bh ./,使其成为一个相对路径,或者用您需要的任何东西替换 ./


更新:

正如上面的示例显示了如何从命令行执行此操作,下面是如何将其添加到您的 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文档。

@ 锋利的机器简化现有的 回答

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 中指定基标记。

这个工作对我来说很好的推动环境

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

在 angular4中,您还可以在. angle-cli. json 应用程序中配置 baseHref。

在。角-cli。 json

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

这将把 index.html 中的 base href 更新为 MY _ APP _ BASE _ HREF _ 1

ng build --app myapp1

如果使用 Angular CLI 6,可以使用 Angular.json 中的 loyUrl/baseHref 选项(project > xxx > Architect > build > configuration > production)。通过这种方式,您可以轻松地为每个项目指定 baseUrl。

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

老实说,你的案子对我很有利!

我用角度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>

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

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

有一个类似的问题,实际上我结束了在我的网络中探测一些文件的存在。

ProbePath 将是您想要检查的文件的相对 URL (如果您现在位于正确的位置,那么就是一种标记) ,例如‘ asset/images/thisImageAlways赖以存在的文件’

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

我只是变了:

  <base href="/">

回到这里:

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

别忘了以/结尾

在 package.json 中设置标志—— base-href 到相对路径:

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

您可以使用以下命令在 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 {}

我已经迟到了,但是如果你要部署到 IIS,你可以使用重写规则(我相信这也可以用其他的 web 服务器来完成)。

可以在请求 index.html 时修改传出响应的内容,并动态地替换基 href。(必须将 url 重写模块安装到 IIS 中)

下面的示例假设您的 index.html 中有 <base href="/angularapp/">

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<rewrite>
<outboundRules>
<rule name="Modify base href to current path">
<match filterByTags="Base" pattern="^(.*)(/angularapp/)(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="true">
<add input="{REQUEST_URI}" pattern="^(.*)/index.html$"/>
</conditions>
<action type="Rewrite" value="{C:1}/" />
</rule>
</outboundRules>
</rewrite>
</system.webServer>
</configuration>