繁体   English   中英

web.config 重写规则在 Blob 存储中的 Azure 静态网站中不起作用

[英]web.config rewrite rule not working in Azure static website in blob storage

我有一个托管在 Azure blob 存储中的单页 React 应用程序,但收到请求的内容不存在。 深度链接到页面时出错:

在此处输入图片说明

我在存储帐户中启用了静态网站选项

在此处输入图片说明

这些文件都在 $web 容器中:

在此处输入图片说明

这包括以下带有重写规则的web.config ,应该让 index.html 处理所有路由:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="React 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="/" appendQueryString="true" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

谁能看到我哪里出错了?

如果您将 404 页面指向index.html则可以进行深层链接。 这不是一个完美的解决方案 - 有副作用 - 但它适用于大多数情况。

在此处输入图片说明

Azure 存储 GPv2 中的静态网站与 Azure 应用服务不同。 它只托管这些静态网页文件,包括 HTML/CSS/JavaScript 文件,其他文件可以在浏览器中处理,如图像、 robots.txt等。由于没有 IIS,它无法处理服务器端脚本。 所以你的web.config文件改变访问路由并属于IIS的服务器端脚本是没有意义的。

实际上,您可以在 Azure 门户中看到这些字样。

为静态网站托管配置 blob 服务使您可以在存储帐户中托管静态内容。 网页可能包括静态内容和客户端脚本。 Azure 存储不支持服务器端脚本。 了解更多

并参考Static website hosting in Azure StorageStatic website hosting in Azure StorageLearn more链接

与静态网站托管相比,依赖服务器端代码的动态网站最好使用 Azure 应用服务托管。

如果需要 URL 重写功能,我建议为您的应用程序使用 Azure 应用服务。

虽然接受的答案是正确的,它说静态网站不能很好地处理 web.config,但你不能使用静态网站做你想做的事是错误的 您可以执行以下操作:

  1. 单击“Azure CDN”标签(静态网站下方)
  2. 创建一个新的 CDN 配置文件(注意选择 WEB(静态网站)链接而不是 BLOB。
  3. 在“所有资源”上输入新的 CDN 配置文件。
  4. 单击您在“概览”中看到的单个端点。
  5. 点击“规则引擎”
  6. 添加以下规则:

在此处输入图片说明

积分:我的回答基于 Andreas Wendl 的回答,您可以在这里找到( https://stackoverflow.com/a/59974770/3231884 )。 我添加了一些细节,因为在检查了他的答案后,我花了几个小时才确切地了解我必须做什么。

好了,您现在可以完美地看到 Andreas 所说的屏幕

我有带有深层链接的多语言 Angular 应用程序(应该直接访问),我做了以下事情:

$web contrainer 中的文件夹结构:

. ru-UA
. uk
. en-US
. index.html
  1. 对 Azure 门户中静态网站设置中的index.html启用 404
  2. 在您的根index.html添加下一个代码:
<html>
<head>
<script>
 if (window.location.pathname != null) {
     const segments = window.location.pathname.split('/').filter(x => x.length > 0);
     const languages = ['ru-UA', 'uk', 'en-US'];

     if (languages.indexOf(segments[0]) >= 0)
     {
         sessionStorage.setItem('path', window.location.pathname);
         window.location = '/' + segments[0] + '/';
     } else {
         window.location = '/uk/'; // It might be your default language
     }
 }
</script>
</head>
</html>
  1. 然后,在您的 Angular 中添加以下内容:
     const spaRedirect = sessionStorage.getItem('path');
     if (spaRedirect) {
         const path = spaRedirect.split('/').filter(x => x.length > 0).slice(1).join('/'); // slice(1) to remove language segment
         await this.router.navigate(['/' + path]);
         sessionStorage.removeItem('path');
     }

现在您可以进行深层链接。

这个怎么运作:

  1. 用户在浏览器中输入: www.domain.com/uk/very/deep/link Azure
  2. 静态网站引擎找不到这样的 blob 并重定向到 400,即 root index.html -> www.domain.com/index.html
  3. index.html通过pathname属性获得完整链接并将其拆分为段。

    实际上,您可以避免按段拆分,但对我而言,这只是额外的验证步骤。

  4. 然后它重定向到适当文件夹中的 Angular 本地化特定index.html ,Angular Engine 开始服务网站-> www.domain.com/uk/index.html

    请注意,您可以在此处延迟,因为您必须使用所有依赖项启动 Angular,并且只有在重定向之后

  5. 您非常基本的组件在sessionStorage.getItem('path')找到了一些东西,并使基于 Angular 的重定向到深层链接。 -> www.domain.com/uk/very/deep/link

这些解决方案都不适合我,我悲惨地开始接受我无法仅在 Azure 存储中托管我的 Angular 应用程序(使用路由)。

但是,实际上,我找到了解决方案。

您需要手动将web.config文件添加到您的src文件夹(是的,即使我们没有在 IIS 服务器上托管它)

 <configuration>
    <system.webServer>
        <rewrite>
          <rules>
            <rule name="Main Rule" 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>
    </system.webServer>
  </configuration>

...然后将此文件添加到angular.json文件中的assets部分:

  "architect": {
    "build": {
      "builder": "@angular-devkit/build-angular:browser",
      "options": {
        . . . 
        "assets": [
          "src/web.config"
        ],

令人震惊的是,这现在有效。

在我的 Angular 应用程序中,我可以点击各种子页面,例如

http://www.mikesapp.web.core.windows.net/Orders/List

而且,至关重要的是,我还可以打开浏览器并直接访问此网页。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM