将 Angular 应用的多个版本部署到 Azure 应用服务
Deploying multiple versions of Angular app to Azure App Service
我有一个 Angular 应用程序,我可以毫无问题地将其部署到 Azure App Service。
首先,我使用以下命令编译我的应用程序:
ng build --output-path=dist --aot -prod
然后我将以下 web.config
添加到 dist
文件夹中:
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="AngularJS Routes" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
<caching enabled="true" enableKernelCache="true">
<profiles>
<add extension=".js" policy="DisableCache" kernelCachePolicy="DisableCache" />
</profiles>
</caching>
</system.webServer>
</configuration>
然后我将 dist
文件夹的内容压缩并拖到我的 Azure 应用程序 (https://<site.scm.azurewebsites.net>/ZipDeploy
) 中。此时应用程序运行正常。
我的问题是我想为不同的语言环境部署不同版本的应用程序。
我使用以下命令编译我的不同版本:
ng build --output-path=dist/en --aot -prod --bh /en/ --i18n-format=xlf --locale=en
ng build --output-path=dist/fr --aot -prod --bh /fr/ --i18n-file=src/locale/messages.fr.xlf --i18n-format=xlf --locale=fr
这会将文件夹 en
和 fr
输出到 /dist
,其中包含应用程序的不同版本。我在应用程序的每个版本中添加了一个 web.config
,例如在 /dist/en
和 dist/fr
.
中
接下来,我压缩 en 和 fr 文件夹并使用 ZipDeploy
如上所述进行部署。
我可以在以下位置看到我的应用程序主页运行良好:
https://<site>.azurewebsites.net/en
https://<site>.azurewebsites.net/fr
但是 - 当我在 https://<site>.azurewebsites.net/fr/redirect.html#state....
被重定向到我的应用程序时(我正在使用 Azure B2C 登录),我收到以下错误:
You do not have permission to view this directory or page.
这感觉就像 iis 试图将我的 url 从字面上解释为一个目录,而不是让 Angular 处理路由,但我不确定。
有人知道如何正确执行此操作吗?
我想我们必须有特定的路由到每个语言环境,如下所示
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Angular Routes fr" stopProcessing="true">
<match url="fr/*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/fr" />
</rule>
<rule name="Angular Routes en" stopProcessing="true">
<match url="en/*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/en" />
</rule>
<rule name="Angular Routes default" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/en" />
</rule>
</rules>
</rewrite>
</system.webServer>
我们用 angular-cli 创建的 i18n 多语言网站也有问题。
您需要:
1) 确保根文件夹中只有 1 个 web.config(不在 ./fr 或 ./en 下)
2) 确保您的 fr/index.html 具有正确的基本标签
<base href="/fr/">
3) 确保您的 en/index.html 具有正确的基本标签
<base href="/en/">
4) 你的独特web.config内容需要包含以下代码:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="SPA Routes FR" stopProcessing="true">
<match url="fr/.*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
</conditions>
<action type="Rewrite" appendQueryString="true" url="fr/index.html" />
</rule>
<rule name="SPA Routes EN" stopProcessing="true">
<match url="en/.*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
</conditions>
<action type="Rewrite" appendQueryString="true" url="en/index.html" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
如果您的 URL 有一些查询参数,则需要 "appendQueryString"。
对于寻找通用解决方案的任何人,请参见下文。
它做了两件事:
- 通过重定向处理默认语言(我们的默认语言是
de
)
- 处理任何语言的重新布线
- 它使用正则表达式从路径的开头捕获语言部分(2 个字符的语言字符串 + 斜杠),例如
de/
或 en/
- 然后使用捕获组重写路径
注:
- 这不会限制用户可以通过 url
请求的语言代码
- 如果您想具体说明支持哪些语言,可以将正则表达式替换为以下内容以仅支持 de + en + fr:
^((?:de|en|fr)\/).*
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<httpRedirect enabled="true">
<add wildcard="/" destination="/de" />
</httpRedirect>
<rewrite>
<rules>
<rule name="angular" stopProcessing="true">
<match url="^(.{2}\/).*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
我有一个 Angular 应用程序,我可以毫无问题地将其部署到 Azure App Service。
首先,我使用以下命令编译我的应用程序:
ng build --output-path=dist --aot -prod
然后我将以下 web.config
添加到 dist
文件夹中:
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="AngularJS Routes" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
<caching enabled="true" enableKernelCache="true">
<profiles>
<add extension=".js" policy="DisableCache" kernelCachePolicy="DisableCache" />
</profiles>
</caching>
</system.webServer>
</configuration>
然后我将 dist
文件夹的内容压缩并拖到我的 Azure 应用程序 (https://<site.scm.azurewebsites.net>/ZipDeploy
) 中。此时应用程序运行正常。
我的问题是我想为不同的语言环境部署不同版本的应用程序。
我使用以下命令编译我的不同版本:
ng build --output-path=dist/en --aot -prod --bh /en/ --i18n-format=xlf --locale=en
ng build --output-path=dist/fr --aot -prod --bh /fr/ --i18n-file=src/locale/messages.fr.xlf --i18n-format=xlf --locale=fr
这会将文件夹 en
和 fr
输出到 /dist
,其中包含应用程序的不同版本。我在应用程序的每个版本中添加了一个 web.config
,例如在 /dist/en
和 dist/fr
.
接下来,我压缩 en 和 fr 文件夹并使用 ZipDeploy
如上所述进行部署。
我可以在以下位置看到我的应用程序主页运行良好:
https://<site>.azurewebsites.net/en
https://<site>.azurewebsites.net/fr
但是 - 当我在 https://<site>.azurewebsites.net/fr/redirect.html#state....
被重定向到我的应用程序时(我正在使用 Azure B2C 登录),我收到以下错误:
You do not have permission to view this directory or page.
这感觉就像 iis 试图将我的 url 从字面上解释为一个目录,而不是让 Angular 处理路由,但我不确定。
有人知道如何正确执行此操作吗?
我想我们必须有特定的路由到每个语言环境,如下所示
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Angular Routes fr" stopProcessing="true">
<match url="fr/*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/fr" />
</rule>
<rule name="Angular Routes en" stopProcessing="true">
<match url="en/*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/en" />
</rule>
<rule name="Angular Routes default" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/en" />
</rule>
</rules>
</rewrite>
</system.webServer>
我们用 angular-cli 创建的 i18n 多语言网站也有问题。
您需要:
1) 确保根文件夹中只有 1 个 web.config(不在 ./fr 或 ./en 下)
2) 确保您的 fr/index.html 具有正确的基本标签
<base href="/fr/">
3) 确保您的 en/index.html 具有正确的基本标签
<base href="/en/">
4) 你的独特web.config内容需要包含以下代码:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="SPA Routes FR" stopProcessing="true">
<match url="fr/.*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
</conditions>
<action type="Rewrite" appendQueryString="true" url="fr/index.html" />
</rule>
<rule name="SPA Routes EN" stopProcessing="true">
<match url="en/.*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
</conditions>
<action type="Rewrite" appendQueryString="true" url="en/index.html" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
如果您的 URL 有一些查询参数,则需要 "appendQueryString"。
对于寻找通用解决方案的任何人,请参见下文。
它做了两件事:
- 通过重定向处理默认语言(我们的默认语言是
de
) - 处理任何语言的重新布线
- 它使用正则表达式从路径的开头捕获语言部分(2 个字符的语言字符串 + 斜杠),例如
de/
或en/
- 然后使用捕获组重写路径
- 它使用正则表达式从路径的开头捕获语言部分(2 个字符的语言字符串 + 斜杠),例如
注:
- 这不会限制用户可以通过 url 请求的语言代码
- 如果您想具体说明支持哪些语言,可以将正则表达式替换为以下内容以仅支持 de + en + fr:
^((?:de|en|fr)\/).*
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<httpRedirect enabled="true">
<add wildcard="/" destination="/de" />
</httpRedirect>
<rewrite>
<rules>
<rule name="angular" stopProcessing="true">
<match url="^(.{2}\/).*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>