Azure iisnode angularJS 1.x app infinite loop when using $http - angularjs

I'm serving an angular 1.x app using iisnode/Azure from an index.html. The routing works fine, but whenever I load any view that makes an $http resource call it seems to go into an infinite loop. The api is hosted on a different instance. I have tested hitting the instance apiBase/ in postman and it returns the expected response. My web.config for iisnode is below:
<configuration>
<system.webServer>
<rewrite>
<rules>
<clear />
<rule name="AngularJS Conditions" stopProcessing="true">
<match url="(css/.*|images/.*|scripts/.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="None" />
</rule>
<rule name="AngularJS Wildcard" enabled="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="index.html" />
</rule>
</rules>
</rewrite>
Any help is super useful. Very new to iisnode/Azure.

Actually if you are running a pure angularJs SPA on Azure Web App, you don't have necessary to configure a web.config to force the iisnode to execute your application. As the angularJs application is totally pure javascript application and which is ran via the interpreter on client browsers. And the rewrite mode you configured in IIS may the criminal which may break the route event in anguarJs application.
You can try to remove the web.config file and restart your Azure Web Apps.
Furthermore, as I cannot reproduce your issue on my side, if it is convenient of you, please provide the problem project repo on GitHub or anywhere else for us to detect the issue.
update
It may be a common issue if you are using html5mode of angularjs route provider.
Please try to modify your web.config with the following content:
<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" />
<add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>

Related

React: 404 Not Found with Proxy after deploying to IIS

I really need your help and advice on this, I have been searching for 2 weeks and I'am unable to resolve my proxy issues.
I'm setting up the below 'setupProxy.js' to bypass the CORS while requesting the API/Endpoints from the (Web Servers).
However, the proxy and Origin replacement only works from localhost 3000 when using the terminal to run it. For some reasons, It doesn't work after deploying to IIS, it keep getting "404 Not Found". Could you please tell me what should I do to fix the issue here?
setupProxy.js:
app.use('/GCM.Order.API',
createProxyMiddleware({
target:'https://gcm.dellsvc',
secure: false,
changeOrigin: true
})
);
Axios call:
let gcmpapi =
  "/GCM.Order.API/api/v1/orders/purchase-summary-with-details"
Terminal/Localhost:3000 result: (200 ok)
However, in IIS browse :8080 (http) : (404 Not Found)
web.config file:
<?xml version="1.0"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Rewrite Text Requests" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{HTTP_METHOD}" pattern="^GET$" />
<add input="{HTTP_ACCEPT}" pattern="^text/html" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="/index.html" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
i had exactly the same problem i was dealing with for 2 weeks. Finally I have a satisfactory solution.
http-proxy-middleware or proxy in package.json is intended (in my opinion) for development purposes only.
What you have created is absolutely correct, but you can only use it in development.
For production settings, is only handled at the url rewrite level. And I think it's logical. It's separate from the code, and if there's an error in the code (eg a bad endpoint pointing to localhost), it won't affect production.
The solution is to modify the url rewrite in the web.config file, which is stored securely in IIS.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Reverse Proxy to api" stopProcessing="true">
<match url="^api/(.*)" />
<action type="Rewrite" url="https://api.example.com/{R:0}" />
</rule>
<rule name="Reverse Proxy to pusher" stopProcessing="true">
<match url="^pusher/(.*)" />
<action type="Rewrite" url="https://pusher.example.com/{R:0}" />
</rule>
<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="/" />
</rule>
</rules>
</rewrite>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>

React Deployment in Azure DevOps

When i try to navigate to a particular route or page the app says "The resource you are looking for has been removed, had its name changed, or is temporarily unavailable." and also the fonts are not loaded, Only the initial page is loaded no other navigation is happening. Can anyone help me out?
Font not loaded and the path font after npm run build is static/media/font_name
You need a web.config file in your public folder to implement client side routing. React uses client side routing and your server should know to allow that.
Add a web.config file in your public directory with the content below:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Static Assets" stopProcessing="true">
<match url="([\S]+[.](html|htm|svg|js|css|png|gif|jpg|jpeg))" />
<action type="Rewrite" url="/{R:1}"/>
</rule>
<rule name="ReactRouter 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="/index.html" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
create .htaccess file in public folder with the below code:
RewriteEngine On
RewriteRule "^[^\.]+$" "index.html"

.net core 3.1 / react app in Azure does not load

I've just created an empty .net core 3.1 / react app with the dotnet cli (dotnet new react -o new-app) and published it into Azure (via WebDeploy base on the downloaded publish profile).
The publish runs successful every time but after it I can't access the client app. The only thing I can see is the default page of azure:
Other parts of the application are working because if I call any endpoint then I got the correct response (e.g. the example action in the example controller of the template returns a valid json).
How should I change to access the client app?
I found the solution. I had to modifiy the web.config because of the client side routing. It is described below:
added a rule to pont the root url to wwwroot/index.html
<rule name="empty-root-index" stopProcessing="true">
<match url="^$" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_METHOD}" pattern="GET|HEAD" />
<add input="{QUERY_STRING}" pattern="^$|^lc=" />
</conditions>
<action type="Rewrite" url="wwwroot/index.html" />
</rule>
an other one which gets all the static content from wwwroot (where the client app lives)
<rule name="wwwroot-static" stopProcessing="true">
<match url="([\S]+[.](html|htm|svg|js|css|png|gif|jpg|jpeg|ico))" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_METHOD}" pattern="GET|HEAD" />
</conditions>
<action type="Rewrite" url="wwwroot/{R:1}" />
</rule>
also one needed to get the client side routing work:
<rule name="html5-routes" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{HTTP_METHOD}" pattern="GET|HEAD" />
</conditions>
<action type="Rewrite" url="wwwroot/index.html" />
</rule>
last but not least the we have to set the mime types
<handlers>
<add name="StaticFileModuleHtml" path="*.htm*" verb="*" modules="StaticFileModule" resourceType="File" requireAccess="Read" />
<!-- More goes here -->
<handlers>

Azure App Service Deploy does not deploy web app successfully

I am a newbie to React
I created a node app service in the Azure Portal using the Node JS Empty web App Starter web app.
When I go to the URL I see
Hello, world!
Which I note is in the contents of server.js
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('Hello, world!');
}).listen(process.env.PORT || 8080);
I see that web.config refers to server.js
<configuration>
<system.webServer>
<handlers>
<!-- indicates that the app.js file is a node.js application to be handled by the iisnode module -->
<add name="iisnode" path="server.js" verb="*" modules="iisnode" />
</handlers>
<rewrite>
<rules>
<!-- Don't interfere with requests for logs -->
<rule name="LogFile" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^[a-zA-Z0-9_\-]+\.js\.logs\/\d+\.txt$" />
</rule>
<!-- Don't interfere with requests for node-inspector debugging -->
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^server.js\/debug[\/]?" />
</rule>
<!-- First we consider whether the incoming URL matches a physical file in the /public folder -->
<rule name="StaticContent">
<action type="Rewrite" url="public{REQUEST_URI}" />
</rule>
<!-- All other URLs are mapped to the Node.js application entry point -->
<rule name="DynamicContent">
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True" />
</conditions>
<action type="Rewrite" url="server.js" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
When I deploy my static react website files to the site, I can see the files are there but the web site itself does not change when I go to the URL.
I think what I need is for the website to start src\app.js instead of server.js
How do I do that?
I tried replacing server.js with ./src/App.js but then the App.js just displays as text.
This Burke Holland shows how to set up the pipeline ( near the bottom)
And also links to this article by Tony Patrina that shows how to set up web.config.
As follows;
<?xml version="1.0"?>
<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" />
<add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>

IIS rewrite condition for React MVC App

I have created a create-react-app and am trying to publish to a production site.
My goal is to have all calls to /api/* go through to the MVC Server application's controller.
Also serve any static files from /content/* and /static/*
All other calls should serve the 1 file /index.html (which is where my react files live and they will handle the routing.
I am using the IIS Rewrite module, and I am trying to use the requested URL "Does Not MAtch the pattern" with regexp.
MY current IIS setup ignores the "do not rewrite if pattern matches" and rewrites everything to index.html
Here is the IIS setup:
and here is the web.config. I'm not sure what I am doing wrong.
<rewrite>
<rules>
<rule name="React Rewrite" enabled="true" patternSyntax="ECMAScript">
<match url="(.*)/api/(.*)|(.*)/content/(.*)|(.*)/static/(.*)" negate="true" />
<action type="Rewrite" url="/index.html" />
<conditions>
</conditions>
</rule>
</rules>
</rewrite>
I've solved it by using the Conditions. My solution is:
<rewrite>
<rules>
<rule name="React Rewrite" enabled="true" patternSyntax="ECMAScript">
<match url="(.*)" negate="false" />
<action type="Rewrite" url="/index.html" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_URI}" pattern="^(/api/)" negate="true" />
<add input="{REQUEST_URI}" pattern="^(/content/)" negate="true" />
<add input="{REQUEST_URI}" pattern="^(/static/)" negate="true" />
</conditions>
</rule>
</rules>
</rewrite>

Resources