简体   繁体   English

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

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

I have a single page React app hosted in Azure blob storage but am getting an The requested content does not exist.我有一个托管在 Azure blob 存储中的单页 React 应用程序,但收到请求的内容不存在。 error when deep linking into a page:深度链接到页面时出错:

在此处输入图片说明

I've enabled static website option in the storage account:我在存储帐户中启用了静态网站选项

在此处输入图片说明

The files are all in place in the $web container:这些文件都在 $web 容器中:

在此处输入图片说明

This includes the following web.config with a rewrite rule that is supposed to let index.html handle all the routing:这包括以下带有重写规则的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>

Can anyone see where I've gone wrong?谁能看到我哪里出错了?

You can do the deep linking if you point the 404 page back at your index.html .如果您将 404 页面指向index.html则可以进行深层链接。 This is not a perfect solution - has side effects - but it will work for the majority of cases.这不是一个完美的解决方案 - 有副作用 - 但它适用于大多数情况。

在此处输入图片说明

The static website in Azure Storage GPv2 is different from Azure App Service. Azure 存储 GPv2 中的静态网站与 Azure 应用服务不同。 It only hosts these static web files which include HTML/CSS/JavaScript files, other files can be handled in browser like images, robots.txt , etc. It has inability to process server-side scripts, due to there is not IIS.它只托管这些静态网页文件,包括 HTML/CSS/JavaScript 文件,其他文件可以在浏览器中处理,如图像、 robots.txt等。由于没有 IIS,它无法处理服务器端脚本。 So your web.config file is no sense for it to change the access routing and be belong to server-side script for IIS.所以你的web.config文件改变访问路由并属于IIS的服务器端脚本是没有意义的。

Actually, you can see the words in Azure portal.实际上,您可以在 Azure 门户中看到这些字样。

Configuring the blob service for static website hosting enables you to host static content in your storage account.为静态网站托管配置 blob 服务使您可以在存储帐户中托管静态内容。 Webpages may include static content and client-side scripts.网页可能包括静态内容和客户端脚本。 Server-side scripting is not supported in Azure Storage. Azure 存储不支持服务器端脚本。 Learn more 了解更多

And refer to the Learn more link of Static website hosting in Azure Storage并参考Static website hosting in Azure StorageStatic website hosting in Azure StorageLearn more链接

In contrast to static website hosting, dynamic sites that depend on server-side code are best hosted using Azure App Service.与静态网站托管相比,依赖服务器端代码的动态网站最好使用 Azure 应用服务托管。

I recommended using Azure App Service for your app if requires the URL-rewrite feature.如果需要 URL 重写功能,我建议为您的应用程序使用 Azure 应用服务。

Although the accepted answer is right when it says that static websites don't process nicely the web.config, it is false that you cannot do what you want using a static website .虽然接受的答案是正确的,它说静态网站不能很好地处理 web.config,但你不能使用静态网站做你想做的事是错误的 Here's what you can do:您可以执行以下操作:

  1. Click on the 'Azure CDN' tag (below Static Website)单击“Azure CDN”标签(静态网站下方)
  2. Create a new CDN Profile (be careful to select the WEB (static website) link and not BLOB.创建一个新的 CDN 配置文件(注意选择 WEB(静态网站)链接而不是 BLOB。
  3. Enter the newly CDN profile on 'All Resources'.在“所有资源”上输入新的 CDN 配置文件。
  4. Click on the single endpoint you see in 'Overview'.单击您在“概览”中看到的单个端点。
  5. Click on 'Rules Engine'点击“规则引擎”
  6. Add the following rule:添加以下规则:

在此处输入图片说明

Credits: My answer is based on Andreas Wendl answer which you can find here ( https://stackoverflow.com/a/59974770/3231884 ).积分:我的回答基于 Andreas Wendl 的回答,您可以在这里找到( https://stackoverflow.com/a/59974770/3231884 )。 I added some detail because after checking his answer it took me a couple of hours to understand exactly what I had to do.我添加了一些细节,因为在检查了他的答案后,我花了几个小时才确切地了解我必须做什么。

There you go, you can now see perfectly the screen Andreas is speaking of好了,您现在可以完美地看到 Andreas 所说的屏幕

I have multi-lingual Angular application with deep linking (which should be accessed directly) and I did the following:我有带有深层链接的多语言 Angular 应用程序(应该直接访问),我做了以下事情:

Folder structure in the $web contrainer: $web contrainer 中的文件夹结构:

. ru-UA
. uk
. en-US
. index.html
  1. Enable 404 to the index.html in the static website setup in the Azure Portal对 Azure 门户中静态网站设置中的index.html启用 404
  2. On your root index.html add the next code:在您的根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. Then, in your Angular add the next:然后,在您的 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');
     }

Now you can have deep linking.现在您可以进行深层链接。

How it works:这个怎么运作:

  1. User enters in the browser: www.domain.com/uk/very/deep/link Azure用户在浏览器中输入: www.domain.com/uk/very/deep/link Azure
  2. Static Website engine can't find such blob and redirects to 400, which is root index.html -> www.domain.com/index.html静态网站引擎找不到这样的 blob 并重定向到 400,即 root index.html -> www.domain.com/index.html
  3. Root index.html got full link via pathname property and split it to the segments.index.html通过pathname属性获得完整链接并将其拆分为段。

    Actually, you can avoid splitting by segment, but for me it's just extra validation step.实际上,您可以避免按段拆分,但对我而言,这只是额外的验证步骤。

  4. Then it redirect to Angular localized-specific index.html in appropriate folder and Angular Engine start to serve website -> www.domain.com/uk/index.html然后它重定向到适当文件夹中的 Angular 本地化特定index.html ,Angular Engine 开始服务网站-> www.domain.com/uk/index.html

    Please note, that you can have a delay here, cause you have to launch Angular with all dependencies and only after that redirect请注意,您可以在此处延迟,因为您必须使用所有依赖项启动 Angular,并且只有在重定向之后

  5. Your very basic component finds something in the sessionStorage.getItem('path') and make Angular-based redirect to the deep link.您非常基本的组件在sessionStorage.getItem('path')找到了一些东西,并使基于 Angular 的重定向到深层链接。 -> www.domain.com/uk/very/deep/link

None of these solutions worked for me, and I miserably started to accept that I wouldn't be able to host my Angular application (with Routing) just in Azure Storage.这些解决方案都不适合我,我悲惨地开始接受我无法仅在 Azure 存储中托管我的 Angular 应用程序(使用路由)。

But, actually, I found a solution.但是,实际上,我找到了解决方案。

You need to manually add a web.config file to your src folder (yes, even though we're not hosting this on an IIS server)您需要手动将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>

...then add this file to the assets section in your angular.json file: ...然后将此文件添加到angular.json文件中的assets部分:

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

Shockingly, this works now.令人震惊的是,这现在有效。

In my Angular app, I could click around to various sub-pages, eg在我的 Angular 应用程序中,我可以点击各种子页面,例如

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

and, crucially, I can also open a browser and go directly to this webpage.而且,至关重要的是,我还可以打开浏览器并直接访问此网页。

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

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