I'm trying to get a Blazor WASM app deployed on IIS, following the instructions here.
This is just the out of the box sample Blazor WASM app
I've published the app to a folder
I've added the URL rewriting module to IIS
I've added dynamic compression support to IIS
I created a new web app in the default website and pointed it to the folder where I published the Blazor app
Invoking the app produces a page containing "An unhandled error has occurred. Reload".
Looking at the requests in the browser dev tools, index.html is being fecthed from the wwwroot folder, suggesting that the url rewrite rule is firing, but the requests for css/bootstrap.min.css, _framework/blazor.webassembly.js and css/app.css all fail with status 404 - Not Found.
What am I missing?
Windows 10 2004.
try to set the base path in your index.html file:
<base href="/CoolApp/">
below is the iis application folder path:
you can set it to your publish folder.
web.conifg file:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<staticContent>
<remove fileExtension=".dat" />
<remove fileExtension=".dll" />
<remove fileExtension=".json" />
<remove fileExtension=".wasm" />
<remove fileExtension=".woff" />
<remove fileExtension=".woff2" />
<mimeMap fileExtension=".dll" mimeType="application/octet-stream" />
<mimeMap fileExtension=".dat" mimeType="application/octet-stream" />
<mimeMap fileExtension=".json" mimeType="application/json" />
<mimeMap fileExtension=".wasm" mimeType="application/wasm" />
<mimeMap fileExtension=".woff" mimeType="application/font-woff" />
<mimeMap fileExtension=".woff2" mimeType="application/font-woff" />
</staticContent>
<httpCompression>
<dynamicTypes>
<add mimeType="application/octet-stream" enabled="true" />
<add mimeType="application/wasm" enabled="true" />
</dynamicTypes>
</httpCompression>
<rewrite>
<rules>
<rule name="Serve subdir">
<match url=".*" />
<action type="Rewrite" url="wwwroot\{R:0}" />
</rule>
<rule name="SPA fallback routing" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="wwwroot\" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
index file:
output:
Note: make sure you assign the iis_iusrs and iusr permission to the site folder.
https://learn.microsoft.com/en-us/aspnet/core/blazor/host-and-deploy/?view=aspnetcore-3.1&tabs=visual-studio
Related
step 1 - i have a simple blazor pwa app which we hosting in sub domain.
Step 2 - Created new virtual directory
Step 3 - Uploaded APIERP within that virtaul drectory
As blazor is SPA it stops accesss of virtual directory due to routing
i tried to edit web.config in order to rewrite URL
but cant get it to work
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<staticContent>
<remove fileExtension=".blat" />
<remove fileExtension=".dat" />
<remove fileExtension=".dll" />
<remove fileExtension=".json" />
<remove fileExtension=".wasm" />
<remove fileExtension=".woff" />
<remove fileExtension=".woff2" />
<mimeMap fileExtension=".blat" mimeType="application/octet-stream" />
<mimeMap fileExtension=".dll" mimeType="application/octet-stream" />
<mimeMap fileExtension=".dat" mimeType="application/octet-stream" />
<mimeMap fileExtension=".json" mimeType="application/json" />
<mimeMap fileExtension=".wasm" mimeType="application/wasm" />
<mimeMap fileExtension=".woff" mimeType="application/font-woff" />
<mimeMap fileExtension=".woff2" mimeType="application/font-woff" />
</staticContent>
<httpCompression>
<dynamicTypes>
<add mimeType="application/octet-stream" enabled="true" />
<add mimeType="application/wasm" enabled="true" />
</dynamicTypes>
</httpCompression>
<rewrite>
<rules>
<rule name="Serve subdir">
<match url=".*" />
<action type="Rewrite" url="wwwroot\{R:0}" />
</rule>
<rule name="SPA fallback routing" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="wwwroot\" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
This is default web.config file of blazor
how can add new rule so that it doesnot intercept url for api
e.g mysite.com/apierp/..
A Rewrite action replaces the current URL string with a substitution string. A substitution string must always specify the URL path (for example, contoso/test/default.aspx). Note that substitutions that contain a physical path on a file system (for example, C:\inetpub\wwwroot) are not supported in IIS.
For how to create rewrite rules for URL rewrite module, you can refer to this document. You can also read the URL Rewrite Module Configuration Reference.
In addition, when you get the error while using the URL rewrite module, you can use Failed Request Tracing to trace rewrite rules.
I am trying to deploy angular universal on IIS 10, I followed this article https://www.thecodehubs.com/how-to-deploy-ssr-angular-universal-to-iis/
This is my Web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="iisnode" path="main.js" verb="*" modules="iisnode" />
</handlers>
<rewrite>
<rules>
<rule name="DynamicContent">
<match url="/*" />
<action type="Rewrite" url="main.js"/>
</rule>
<rule name="StaticContent" stopProcessing="true">
<match url="([\S]+[.](jpg|jpeg|gif|css|png|js|ts|cscc|less|ico|html|map|svg))" />
<action type="None" />
</rule>
</rules>
</rewrite>
<staticContent>
<clientCache cacheControlMode="UseMaxAge" />
<remove fileExtension=".svg" />
<remove fileExtension=".eot" />
<remove fileExtension=".ttf" />
<remove fileExtension=".woff" />
<remove fileExtension=".woff2" />
<remove fileExtension=".otf" />
<mimeMap fileExtension=".ttf" mimeType="application/octet-stream" />
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
<mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject" />
<mimeMap fileExtension=".woff" mimeType="application/x-woff" />
<mimeMap fileExtension=".woff2" mimeType="application/x-woff" />
<mimeMap fileExtension=".otf" mimeType="application/otf" />
</staticContent>
</system.webServer>
</configuration>
This is my app folder on IIS
But when i start my website on IIS, I got this error
The iisnode module is unable to start the node.exe process. Make sure the node.exe executable is available at the location specified in the system.webServer/iisnode/#nodeProcessCommandLine element of web.config. By default node.exe is expected in one of the directories listed in the PATH environment variable.
So I added this line to my web.config file just before </system.webServer>
<iisnode nodeProcessCommandLine="C:\Program Files\nodejs\node.exe" />
</system.webServer>
</configuration>
But the same problem still exists. this is my ProgramFiles, here i noticed that the nodejs has shortcut , I am using nvm (node version manager). Is this the reason ?
Yes you are right, this is because you are using nvm, i faced this issue before.
Switch off node version manager by running in cmd
nvm off
Install node js on your machine, then it will run without any issue.
As a Blazor developer I don't think there is a good documentation on this topic.
I have uploaded a very simple Blazor webassembly(v5) website with only 1 page now it takes more than 20 seconds to load in browser. I tried to use compression based on this Microsoft doc and used the web.config file suggested by the document.
I have also installed URL Rewrite module, Microsoft IIS Compression, StaticCompresstionModule and DynamicCopressionModule and tried modifying the web.config's following lines but it did not worked at all :
web.config :
...
<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
<scheme name="br" dll="%ProgramFiles%\IIS\IIS Compression\iisbrotli.dll" />
<scheme name="gzip" dll="%ProgramFiles%\IIS\IIS Compression\iiszlib.dll" />
....
The result still is not compressed and here is my browser's developer tool screenshot :
This can be a problem for everyone who uses Blazor as the front-end.
Can any one please provide a step-by-step working answer ?
Update : here is my final web.config (which does not work):
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<staticContent>
<remove fileExtension=".blat" />
<remove fileExtension=".dat" />
<remove fileExtension=".dll" />
<remove fileExtension=".json" />
<remove fileExtension=".wasm" />
<remove fileExtension=".woff" />
<remove fileExtension=".woff2" />
<mimeMap fileExtension=".blat" mimeType="application/octet-stream" />
<mimeMap fileExtension=".dll" mimeType="application/octet-stream" />
<mimeMap fileExtension=".dat" mimeType="application/octet-stream" />
<mimeMap fileExtension=".json" mimeType="application/json" />
<mimeMap fileExtension=".wasm" mimeType="application/wasm" />
<mimeMap fileExtension=".woff" mimeType="application/font-woff" />
<mimeMap fileExtension=".woff2" mimeType="application/font-woff" />
<mimeMap fileExtension=".js.gz" mimeType="application/javascript" />
<mimeMap fileExtension=".dat.gz" mimeType="application/octet-stream" />
<mimeMap fileExtension=".dll.gz" mimeType="application/octet-stream" />
<mimeMap fileExtension=".json.gz" mimeType="application/json" />
<mimeMap fileExtension=".wasm.gz" mimeType="application/wasm" />
<mimeMap fileExtension=".blat.gz" mimeType="application/octet-stream" />
<mimeMap fileExtension=".html.gz" mimeType="text/html" />
<mimeMap fileExtension=".css.gz" mimeType="text/css" />
<mimeMap fileExtension=".ico.gz" mimeType="image/x-icon" />
<mimeMap fileExtension=".svg.gz" mimeType="image/svg+xml" />
<mimeMap fileExtension=".js.br" mimeType="application/javascript" />
<mimeMap fileExtension=".dat.br" mimeType="application/octet-stream" />
<mimeMap fileExtension=".dll.br" mimeType="application/octet-stream" />
<mimeMap fileExtension=".json.br" mimeType="application/json" />
<mimeMap fileExtension=".wasm.br" mimeType="application/wasm" />
<mimeMap fileExtension=".blat.br" mimeType="application/octet-stream" />
<mimeMap fileExtension=".html.br" mimeType="text/html" />
<mimeMap fileExtension=".css.br" mimeType="text/css" />
<mimeMap fileExtension=".ico.br" mimeType="image/x-icon" />
<mimeMap fileExtension=".svg.br" mimeType="image/svg+xml" />
</staticContent>
<rewrite>
<outboundRules rewriteBeforeCache="true">
<rule name="Add Vary Accept-Encoding" preCondition="PreCompressedFile" enabled="true">
<match serverVariable="RESPONSE_Vary" pattern=".*" />
<action type="Rewrite" value="Accept-Encoding" />
</rule>
<rule name="Add Encoding Brotli" preCondition="PreCompressedBrotli" enabled="true" stopProcessing="true">
<match serverVariable="RESPONSE_Content_Encoding" pattern=".*" />
<action type="Rewrite" value="br" />
</rule>
<rule name="Add Encoding Gzip" preCondition="PreCompressedGzip" enabled="true" stopProcessing="true">
<match serverVariable="RESPONSE_Content_Encoding" pattern=".*" />
<action type="Rewrite" value="gzip" />
</rule>
<preConditions>
<preCondition name="PreCompressedFile">
<add input="{HTTP_URL}" pattern="\.(gz|br)$" />
</preCondition>
<preCondition name="PreCompressedBrotli">
<add input="{HTTP_URL}" pattern="\.br$" />
</preCondition>
<preCondition name="PreCompressedGzip">
<add input="{HTTP_URL}" pattern="\.gz$" />
</preCondition>
</preConditions>
</outboundRules>
<rules>
<rule name="Serve subdir">
<match url=".*" />
<action type="Rewrite" url="wwwroot\{R:0}" />
</rule>
<rule name="Rewrite brotli file" stopProcessing="true">
<match url="(.*)"/>
<conditions>
<add input="{HTTP_ACCEPT_ENCODING}" pattern="br" />
<add input="{REQUEST_FILENAME}" pattern="\.(js|dat|dll|json|wasm|blat|htm|html|css|ico|svg)$" />
<add input="{REQUEST_FILENAME}.br" matchType="IsFile" />
</conditions>
<action type="Rewrite" url="{R:1}.br" />
</rule>
<rule name="Rewrite gzip file" stopProcessing="true">
<match url="(.*)"/>
<conditions>
<add input="{HTTP_ACCEPT_ENCODING}" pattern="gzip" />
<add input="{REQUEST_FILENAME}" pattern="\.(js|dat|dll|json|wasm|blat|htm|html|css|ico|svg)$" />
<add input="{REQUEST_FILENAME}.gz" matchType="IsFile" />
</conditions>
<action type="Rewrite" url="{R:1}.gz" />
</rule>
<rule name="SPA fallback routing" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="wwwroot\" />
</rule>
</rules>
</rewrite>
<httpCompression>
<dynamicTypes>
<add mimeType="application/octet-stream" enabled="true" />
<add mimeType="application/json" enabled="true" />
<add mimeType="application/wasm" enabled="true" />
<add mimeType="application/font-woff" enabled="true" />
</dynamicTypes>
<staticTypes>
<add mimeType="application/octet-stream" enabled="true" />
<add mimeType="application/json" enabled="true" />
<add mimeType="application/wasm" enabled="true" />
<add mimeType="application/font-woff" enabled="true" />
</staticTypes>
</httpCompression>
</system.webServer>
</configuration>
TL;DR
Most likely you have a site misconfiguration issue in IIS. To confirm it, please check if your site configuration will load in Configuration Editor:
Select your website
Double-click on Configuration Editor
Check if this gives you an error
Then work your way through the errors and eliminate them one by one by updating your site configuration.
The challenge is that it's hard to provide a universally working example since it depends on many unknowns: OS version, IIS version, existing configs, etc.
Detailed steps
There are two ways for how it can be done: using IIS Compression scheme providers (Option 1) or using rewrites (Option 2).
Prerequisites
Here is what I used for my setup:
Windows 10 Pro
IIS version 10.0
Installed URL Rewrite Module
Dynamic Content Compression and Static Content Compression IIS features are enabled in Turn Windows features on or off dialog
New Blazor app created with .NET5.0 dotnet new blazorwasm
Option 1: Adding compression using IIS Compression scheme providers
Install Microsoft IIS Compression
Update your site configuration
Note: it seems like the suggested configuration won't work by default in IIS. I had to remove some entries from it because they were duplicates of the entries in the IIS machine config.
Here is a configuration that finally worked for me:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<staticContent>
<remove fileExtension=".blat" />
<remove fileExtension=".dat" />
<remove fileExtension=".dll" />
<remove fileExtension=".json" />
<remove fileExtension=".wasm" />
<remove fileExtension=".woff" />
<remove fileExtension=".woff2" />
<mimeMap fileExtension=".blat" mimeType="application/octet-stream" />
<mimeMap fileExtension=".dll" mimeType="application/octet-stream" />
<mimeMap fileExtension=".dat" mimeType="application/octet-stream" />
<mimeMap fileExtension=".json" mimeType="application/json" />
<mimeMap fileExtension=".wasm" mimeType="application/wasm" />
<mimeMap fileExtension=".woff" mimeType="application/font-woff" />
<mimeMap fileExtension=".woff2" mimeType="application/font-woff" />
</staticContent>
<rewrite>
<rules>
<rule name="Serve subdir">
<match url=".*" />
<action type="Rewrite" url="wwwroot\{R:0}" />
</rule>
<rule name="SPA fallback routing" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="wwwroot\" />
</rule>
</rules>
</rewrite>
<urlCompression doStaticCompression="true" doDynamicCompression="true" />
<httpCompression>
<dynamicTypes>
<add mimeType="application/octet-stream" enabled="true" />
<add mimeType="application/json" enabled="true" />
<add mimeType="application/wasm" enabled="true" />
<add mimeType="application/font-woff" enabled="true" />
</dynamicTypes>
<staticTypes>
<add mimeType="application/octet-stream" enabled="true" />
<add mimeType="application/json" enabled="true" />
<add mimeType="application/wasm" enabled="true" />
<add mimeType="application/font-woff" enabled="true" />
</staticTypes>
</httpCompression>
</system.webServer>
</configuration>
Option 2: Adding compression using rewrites
Download the web.config provided in this article
Go through similar activities as above, eliminating all web.config inconsistencies.
Note: In my case, I had to remove mimeMap for .wasm due to duplication reported by IIS:
...
<staticContent>
<remove fileExtension=".dll" />
<remove fileExtension=".json" />
<remove fileExtension=".woff" />
<remove fileExtension=".woff2" />
<remove fileExtension=".wasm" /> <!-- added this line -->
<mimeMap fileExtension=".json" mimeType="application/json" />
...
Results
And as a result, for either option, you should be able to see the following.
for HTTP
for HTTPs
First, you need to follow prerequisites steps that Sasha mentioned.
After compression already set on server, modify the web.config using web.config mentioned in options 2.
Don't forget add this line in your web.config
<remove fileExtension=".wasm" />
Before I added the above, my apps got an error when loading.
After that, you can clear your browser cache and history to test it.
I started investigating the problem using this topic, and this is by far the best web.config I found:
https://github.com/dotnet/AspNetCore.Docs/blob/main/aspnetcore/blazor/host-and-deploy/webassembly/_samples/web.config
It worked like a charm: the initial loading time (no browser cache) was shorted from ~20 seconds to ~1.2 seconds. My configuration is as above: IIS hosted Blazor client application.
I use compression-webpack-plugin for compressing my javascript files into gz format in my ASP.NET MVC 5 project.
Part of my webpack.config.js with compression-webpack-plugin settings:
const CompressionPlugin = require('compression-webpack-plugin');
module.exports = {
//...
plugins: [
//...
new CompressionPlugin({
test: /\.(js|css)$/,
filename: '[path].gz[query]',
algorithm: 'gzip',
deleteOriginalAssets: true
}),
],
//...
};
It's works fine:
The next step is enabling GZIP compression in IIS, so first of all I make sure that I have necessary features in Windows Features:
... and enabling compression for my app directly in IIS like on the below picture.
Additionaly I've added this piece of code to my Web.config:
<system.webServer>
<urlCompression doStaticCompression="true" doDynamicCompression="true" />
</system.webServer>
After building scripts are not loaded by web browser - I've got warnings for every script file in console:
Loading failed for the "script" with source
„http://192.168.100.100:8088/Scripts/dist/runtime.7b9bc97b36a783fd7495.js”.
What have I done wrong? Should I set up something else in my backend? Please notice that I include script with .js extension, not .js.gz - it's a mistake?
Ok, finally, after realy deep searching I've found a solution.
Disable dynamic and static compression in IIS for project (because I've already gziped files so leave CPU alone!)
Download and install URL Rewrite module for IIS from here: https://www.iis.net/downloads/microsoft/url-rewrite
Remove from Web.config below line (if still exists):
<urlCompression doStaticCompression="true" doDynamicCompression="true" />
Add to Web.config below piece of code:
<system.webServer>
<staticContent>
<remove fileExtension=".js.gz" />
<remove fileExtension=".css.gz" />
<remove fileExtension=".png.gz" />
<remove fileExtension=".jpg.gz" />
<remove fileExtension=".gif.gz" />
<remove fileExtension=".svg.gz" />
<remove fileExtension=".html.gz" />
<remove fileExtension=".json.gz" />
<mimeMap fileExtension=".js.gz" mimeType="application/javascript" />
<mimeMap fileExtension=".css.gz" mimeType="text/css" />
<mimeMap fileExtension=".png.gz" mimeType="image/png" />
<mimeMap fileExtension=".jpg.gz" mimeType="image/jpeg" />
<mimeMap fileExtension=".gif.gz" mimeType="image/gif" />
<mimeMap fileExtension=".svg.gz" mimeType="image/svg+xml" />
<mimeMap fileExtension=".html.gz" mimeType="text/html" />
<mimeMap fileExtension=".json.gz" mimeType="application/json" />
</staticContent>
<rewrite>
<outboundRules rewriteBeforeCache="true">
<rule name="Custom gzip file header">
<match serverVariable="RESPONSE_CONTENT_ENCODING" pattern=".*" />
<conditions>
<add input="{REQUEST_URI}" pattern="\.gz$" />
</conditions>
<action type="Rewrite" value="gzip"/>
</rule>
</outboundRules>
<rules>
<rule name="Rewrite gzip file">
<match url="(.*)"/>
<conditions>
<add input="{HTTP_ACCEPT_ENCODING}" pattern="gzip" />
<add input="{REQUEST_FILENAME}.gz" matchType="IsFile" />
</conditions>
<action type="Rewrite" url="{R:1}.gz" />
</rule>
</rules>
</rewrite>
</system.webServer>
Make sure you have .gz in MIME types in IIS:
I am trying to deploy an angular application to Microsoft azure app service via the dist folder. I run the script "ng build --prod" to generate a dist folder, compressed it, and uploaded it to the deploy site for azure service. Then only a part of the website is loaded and there are a lot of 404 errors. Here is my temporary web link: https://tes42.azurewebsites.net
The angular application has a rooter called "books", and the index.html file in the dist folder has code. I am thinking if the problem is caused by this?
To fix these 404 errors, you'll need to add a web.config file to your root with the following content:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="AngularJS" stopProcessing="true">
<match url="^(?!.*(.bundle.js|.bundle.map|.bundle.js.gz|.bundle.css|.bundle.css.gz|.png|.jpg|.ico|.svg|.eot|.woff|\.woff2)).*$" />
<conditions logicalGrouping="MatchAll"></conditions>
<action type="Rewrite" url="/" appendQueryString="true" />
</rule>
</rules>
</rewrite>
<staticContent>
<remove fileExtension=".svg" />
<remove fileExtension=".eot" />
<remove fileExtension=".woff" />
<remove fileExtension=".woff2" />
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
<mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject" />
<mimeMap fileExtension=".woff" mimeType="application/font-woff" />
<mimeMap fileExtension=".woff2" mimeType="application/font-woff" />
</staticContent>
</system.webServer>
</configuration>