Angular2 - page refresh 404ing when hosted in Azure - azure

I am working on an Angular2 app. It uses "#angular/common": "2.0.0-rc.4" and "#angular/router": "3.0.0-beta.2".
My problem is that when I use the browser refresh on some of the pages I see an error saying...
"The resource you are looking for has been removed, had its name changed, or is temporarily unavailable."
This also happens if I hit the url directly.
An example url is...
https://tilecasev2.azurewebsites.net/profile/therichmond
However if you view pages via the homepage they work ok but only until refreshed (https://tilecasev2.azurewebsites.net).
I have the below in my index.html head...
<base href="/">
Why does this happen and how can I fix it?

HashLocationStrategy avoids the issue by including a # in all of your angular routes but doesn't really fix it.
To make angular routes without hashes work in azure the same way they do in your local development environment, you just need to configure IIS to rewrite all requests as root. This lets angular handle the routing.
To do this, add a Web.config file to your site's root folder with the following contents:
<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>

If you deploying in same app service plan both angular and API project then this the solution.
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Angular" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_URI}" pattern="^/api" negate="true" />
<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>
for more details refer this link https://less0.github.io/azure-angular-II/

As Gunter pointed out HashLocationStrategy needed to be setup.
I followed the steps in the Angular2 docs and it all works now...
https://angular.io/docs/ts/latest/api/common/index/HashLocationStrategy-class.html

Related

On the server controlled by Plesk, node.js only home page get method works

the node.js application I coded works on my own host, locally, etc., but does not work on plesk.
enter image description here
It only works when entering the home page. When I entered the /test directory, it was giving a 404 error. When I add the following web.config
403 - Forbidden: Access is denied.
You do not have permission to view this directory or page using the credentials that you supplied.
I'm starting to get the error. Could you please help I couldn't understand why I can only access the home directory.
<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>

Hidden redirect IIS - web.config

I have an Windows Server hosted (IIS), in the root dir (head dir with FTP) I have a directory /www/ with an Angular SPA built, so an index.html inside.
I want to say to the server:
"Ehi, when people go to https://example.com you must to show www/index.html but with https://example.com on the URL" (so not with https://example.com/www/) is this possible??
And i have to say also:
"Ehi server! The routes are not real directory! This is an SPA!!" becouse the routing navigation is OK but the refresh doesn't works.
I think i have to write something on web.config file, but what?
Thanks in advance!
UPDATE:
I'm using:
<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="/www/" />
</rule>
</rules>
</rewrite>
</system.webServer>
This works for refresh but for "hidden redirect"...

React Router app in IIS inside subdirectory Not Working using URL Rewrite

I have a react router in my react app that I am trying to host in IIS. I have URL Rewrite installed. with the following web.config.
<?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>
If I use localhost:port as the react project's main directory. It works.
However, I need to use a relative path/ a sub-directory. Since we have other applications hosted in the same port.
So I need to host it inside of localhost:80/firstdirectory. This is where index.html will go.
Redirects and Routing are simply not working. If I try to use React Router's redirect to a relative path of '/seconddirectory', it will redirect me to localhost/seconddirectory, instead of localhost:80/firstdirectory/seconddirectory.
Since I use CRA. I have tried this with hostname: '.' and without. It really doesnt want to work.
So far I may have found solutions to my problem. I still need to keep testing to make sure nothing else is affected.
This is the web config that I ended up using, along with URL Rewrite
<?xml version="1.0"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Rewrite Text Requests" enabled="true" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_URI}" pattern="^/subdirectoryhere/api(.*)$" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/subdirectoryhere/index.html" logRewrittenUrl="false" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
I also have
homepage: '.'
in my create-react-app application, which i'll have to move to my own boilerplate later.
I also had to change my i18n.tsx backend loadPath to a relative path
backend: {
loadPath: './locales/{{lng}}.json'
}
Lastly my Router is fed the basename
const getBasename = (path: any) => path.substr(0, path.lastIndexOf('/'));
<Router basename={getBasename(window.location.pathname)}>
...
</Router

IIS Rewrite rule for serverURL/Home/Index/2 URL type

I've implemented Angular 2 app with the routing, its working fine with the URL like serverURL/Home/Index its properly navigating to appropriate component without any errors.
But when I try entering serverURL/Home/Index/2 its giving me the following error
I've written below snippet in the web.config for Rewriting in IIS
<system.webServer>
<rewrite>
<rules>
<rule name="AngularJS" 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="src/" />
</rule>
</rules>
</rewrite>
</system.webServer>
Even I've written { path: "Index/:id", component: IndexComponent }, in the routing file
Please help in this, thanks in advance.

additional paths with azure web app returns error

I made a react app using create-react-app. I am trying to deploy it on azure web app. I created a build and deployed using FTP.
When there is the internal redirect from the react the app I am able to see the webpage. But when I try to directly go to the url, I get this error.
For example:
if base url is www.example.com, and the app internally redirects to /new, the page goes to www.example.com/new. But if I directly try to load www.example.com/new, I get the above shown response. This doesn't happen in local testing
Demo:
I have created a demo here
For it to work for me, I added a web.config-file in the public-folder (this is where favicon.ico, index.html & manifest.json is located), and added the following code:
<?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>
I hope this might help :)
Place the below web.config file under the /site/wwwroot directory
<?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>
When there is the internal redirect from the react the app I am able to see the webpage. But when I try to directly go to the url, I get this error.
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
If you use Network tool to capture network traffic when you click the button New to render (redirect to) the new page, you will find it just changes the URL locally instead of really requesting for http://data-trigger-mass-test.azurewebsites.net/new to the server. When you directly browse and request for http://data-trigger-mass-test.azurewebsites.net/new to the server, the server could not find the resource, so it returns (404) error. In order to make the URL http://data-trigger-mass-test.azurewebsites.net/new work on both server and client-side, you may need to set up routes for it on both server and client side.
Your server should always send the root html file for all client request, so that it can pass routing to react.
If the server is NodeJs, add something like below into your server.js.
app.get('*', (req, res) => {
res.sendFile('public/index.html', { root: __dirname });
});
This worked:
<?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>
I created a web.config file in the public-folder where the index.html is located and added the above code.

Resources