[英]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?谁能看到我哪里出错了?
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 Storage
中Static website hosting in Azure Storage
的Learn 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:您可以执行以下操作:
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
index.html
in the static website setup in the Azure Portal对 Azure 门户中静态网站设置中的index.html
启用 404index.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>
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:这个怎么运作:
www.domain.com/uk/very/deep/link
Azure用户在浏览器中输入: www.domain.com/uk/very/deep/link
Azureindex.html
-> www.domain.com/index.html
静态网站引擎找不到这样的 blob 并重定向到 400,即 root index.html
-> www.domain.com/index.html
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.实际上,您可以避免按段拆分,但对我而言,这只是额外的验证步骤。
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,并且只有在重定向之后
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.