Ok, this is similar to other questions out there but I am not familiar with url rewrite.
I am hosting (hopefully only for development and testing) a react application under IIS.
If hosted in the root of the site folder all is well using
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Static Assets" stopProcessing="true">
<match url="([\S]+[.](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>
But I need it to work in a subapplication. For instance: http://myserver:8888/myapp. Where myapp is the sub application.
IIS diagram:
Sites
- MySite
- MyApp
Better example of the url that includes the route: http://myserver:8888/myapp/1234/abcd.
1234 and abcd are route values/params.
contents of my app directory are:
index.html
main.a9e1df0325f4fdb57e7e.js
vendors~main.c8848853e10f698af19d.js
web.config
Thanks
Gina
You could host your app in any subapplication in iis but be careful to defining correct route for serving contents. It seems you want to host static content so you can't use route parameters in url hence these parameters are used by asp.net. Static content are served by iis. You can try this url for serving content in myapp:
http://myserver:8888/myapp/index.html
Related
I have a React SPA published on IIS which is using React Router for URL routes which is working perfectly however within the public directory i have a sub folder that is completely separate to the React project that im trying to access however it doesnt seem to be working:
URL: http://{REACT_SPA}/Dev (/Dev is a sub folder)
web.config:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="ReactRouter Routes" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="index.html" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
any ideas?
I have several rules in my rewrite, including ARR that have been working for over a year, now it's almost like the top rules in the web.config file are no longer being called in the correct order.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="AuthRoute" stopProcessing="true">
<match url="(auth$|auth/(.*))" />
<action type="Rewrite" url="http://localhost:8083/auth/{R:2}" />
</rule>
...
<rule name="Non-File Routes" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="/index.html" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
As you can see, I have a separate route for /auth that reverse-proxies to a different application designed for everything in /auth ... In this case, there are several files foo.HASH.css and foo.HASH.js that are actually there, the backend application is serving them, but the front end is getting the parent application (via IIS) of the /index.html.
Some files are being reverse proxied correctly, others simply are not. It's weird, I'm not sure if it's a windows/iis update that started this or what.
Turns out the content for the app being reverse proxied wasn't being published with the path prefix. Since browsers aren't showing the full path in the list, the aren't too load from root was missed.
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.
I have a website with the following structure at the root for a Node.js app
package.json
server.js
public
index.html
css
js
images
...other folders
I would like to take the person only inside the public folder with a forced HTTPS connection.
My current web.config file looks like this
<?xml version="1.0" encoding="utf-8"?>
<!--
This configuration file is required if iisnode is used to run node processes behind
IIS or IIS Express. For more information, visit:
https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config
-->
<configuration>
<system.webServer>
<!-- Visit http://blogs.msdn.com/b/windowsazure/archive/2013/11/14/introduction-to-websockets-on-windows-azure-web-sites.aspx for more information on WebSocket support -->
<webSocket enabled="false" />
<handlers>
<!-- Indicates that the server.js file is a node.js site to be handled by the iisnode module -->
<add name="iisnode" path="server.js" verb="*" modules="iisnode"/>
</handlers>
<rewrite>
<rules>
<!-- Do not 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 site entry point -->
<rule name="DynamicContent">
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>
</conditions>
<action type="Rewrite" url="server.js"/>
</rule>
<rule name="Force HTTPS" enabled="true">
<match url="(.*)" ignoreCase="false" />
<conditions>
<add input="{HTTPS}" pattern="off" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" appendQueryString="true" redirectType="Permanent" />
</rule>
<rule name="Redirect rquests to default azure websites domain" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_HOST}" pattern="^zupbot\.azurewebsites\.net$" />
</conditions>
<action type="Redirect" url="https://www.zup.chat/{R:0}" />
</rule>
</rules>
</rewrite>
<!-- 'bin' directory has no special meaning in node.js and apps can be placed in it -->
<security>
<requestFiltering>
<hiddenSegments>
<remove segment="bin"/>
</hiddenSegments>
</requestFiltering>
</security>
<!-- Make sure error responses are left untouched -->
<httpErrors existingResponse="PassThrough" />
<!--
You can control how Node is hosted within IIS using the following options:
* watchedFiles: semi-colon separated list of files that will be watched for changes to restart the server
* node_env: will be propagated to node as NODE_ENV environment variable
* debuggingEnabled - controls whether the built-in debugger is enabled
See https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config for a full list of options
-->
<!--<iisnode watchedFiles="web.config;*.js"/>-->
</system.webServer>
</configuration>
Whenever I try to access my website, it tries finding a server.js and gives me this error
{"code":"NotAuthorized","message":"/server.js"}
My node.js code does this to serve static files
server.get('/.*/', restify.serveStatic({
//Ensure that people can only access the files within the public directory and none of the protected server files
directory: __dirname + '/public',
default: constants.INDEX_HTML,
match: /^((?!server.js).)*$/ // we should deny access to the application source
}));
How can I take the person straight inside the public folder always with an HTTPS connection? Thank you for your help in advance.
UPDATE 1
I added the HTTPS redirect before any other rule that has a stopProcessing=true and it works , however if I go to my native site http://.azurewebsites.net, it still takes me to the https version of it, how can I redirect sitename.azurewebsites.net to the https version of my custom domain?
Please try the following rewrite rules in web.config:
<rule name="DynamicContent" stopProcessing="true">
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>
</conditions>
<action type="Rewrite" url="server.js"/>
</rule>
<rule name="Redirect to https" enabled="true" patternSyntax="ECMAScript" stopProcessing="true">
<match url="(.*)"/>
<conditions>
<add input="{HTTPS}" pattern="Off"/>
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" appendQueryString="true" />
</rule>
Which will rewrite the url your_site.azurewebsites.net/<asset> to https protocol if there is a file named <asset> in public folder as you configured in restify.serveStatic.
And it will not rewrite the url those can match the route setting in your restify application.
Any further concern, please feel free to let me know.
I am deploying a React app to an Azure App Service that uses non-hashed URLs (eg. browserHistory) like
http://mywebapp.azurewebsites.net/map/50.9375/6.9603/13
but that should all be handled by the same index.html for all paths. How do you accomplish this in Azure App Service? Basically, i want all requests against the app service to map to /index.html and let React work it out.
Add a web.config file in the root of your application that you deploy to Azure App Service:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="redirect all requests" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" pattern="" ignoreCase="false" />
</conditions>
<action type="Rewrite" url="/index.html" appendQueryString="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>