I have a Plotly-Dash web application running as a service on a Windows Server 2016 on port 50001.
I can directly access it via its port on a web browser. (working page via direct url)
I configured the IIS server so that requests made to the route /signatures are rewritten to the service on 50001. It seems to correctly request the page, but what I see is a page stuck on the loading screen. (IIS URL not working)
I feel like it is a problem between Dash and IIS but I'm not able to figure out why.
My question is what should I do so that my web page is correctly displayed when I use IIS's URL Rewrite with Dash?
Here is my web.config file:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<clear />
<rule name="signatures" stopProcessing="true">
<match url="^signatures/?(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="http://localhost:50001/{R:1}" />
</rule>
<!-- other rules -->
</rules>
</rewrite>
</system.webServer>
</configuration>
Thanks in advance.
Edit :
Here are the screenshots of the network tab for the two requests:
network tab for direct URL
network tab for rewritten URL
It seems like in the rewritten URL Dash requests all its resources from localhost and cannot get them.
Answer
Apparently I'm banned from answering questions (even my own !!), so I'm adding my answer as an edit.
Based on #JennyDai 's suggestions I found that the client was not requesting the resources from the correct route.
I found a workaround by editing the code to request local resources with the same prefix.
In the creation of my Dash app, I set the parameter requests_pathname_prefix to have the same value as the prefix used in IIS.
app = dash.Dash(
__name__,
external_stylesheets=external_stylesheets,
requests_pathname_prefix=f"/dash/", # <-- same as the prefix in IIS
)
see dash.Dash in the API reference
Full example
Here is a full example for a test app running on port 50010 that should be accessible from http://localhost/dash/
IIS config (web.config)
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<clear />
<!-- other rules -->
<rule name="dash" enabled="true" stopProcessing="true">
<match url="^dash/(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="http://localhost:50010/{R:1}" />
</rule>
<!-- other rules -->
</rules>
</rewrite>
</system.webServer>
</configuration>
Python code
The code is based on this tutorial given by Plotly.
import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.express as px
import pandas as pd
external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]
PORT = 50010
app = dash.Dash(
__name__,
external_stylesheets=external_stylesheets,
requests_pathname_prefix=f"/dash/", # <-- same as the prefix in IIS
)
df = pd.DataFrame(
{
"Fruit": ["Apples", "Oranges", "Bananas", "Apples", "Oranges", "Bananas"],
"Amount": [4, 1, 2, 2, 4, 5],
"City": ["SF", "SF", "SF", "Montreal", "Montreal", "Montreal"],
}
)
fig = px.bar(df, x="Fruit", y="Amount", color="City", barmode="group")
app.layout = html.Div(
children=[
html.H1(children="Hello Dash"),
html.Div(
children="""
Dash: A web application framework for Python.
"""
),
dcc.Graph(id="example-graph", figure=fig),
]
)
if __name__ == "__main__":
app.run_server(debug=True, port=PORT)
After running the server here The page is displayed correctly with a rewritten URL.
Problems with this workaround
Currently, the page does not display correctly when we try to connect directly to the port. I'm fine with how it works for now.
Another problem is that every time we want to change the URL in IIS we will need to redeploy the code with the same edit, but that's a minor problem currently.
Thanks to #JennyDai for their help.
Related
I'm trying to figure out how to reroute just one of our sites from IIS to Apache. I've followed several online tutorials and posts and nothing is working. I keep getting:
I've read that I need to do a reverse proxy using the URL Rewrite feature of IIS. So I did that and here are my settings:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<httpRedirect enabled="false" destination="" />
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://localhost:8088/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Apache is on 8088 and if I hit localhost:8088, it works just fine. I've also added IUSR and IIS_IUSRS users to the directory permissions both having read and execute, list contents, and read permissions. I wouldn't think this would be that terribly hard.
When you need to rewrite IIS to apache, please remember to install ARR.
https://www.iis.net/downloads/microsoft/application-request-routing
Then please remember to enable Server node->application request routing cache->Server Proxy setting->Enable proxy.
Besides, could you access orchestrator.local without URL rewrite rule. Because, if this issue is caused by IIS, you should receive status code more than site can't be reached.
My goal is to be able to access this URL from remote machine via IIS Rewrite:
http://host:5000/#!/room/5963bdd51eeaa415988ec6d9
using the following URL:
http://{host}/chat/
Here's my web.config
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="chat" stopProcessing="true">
<match url="chat/*" />
<action type="Rewrite" url="http://127.0.0.1:5000" />
</rule>
</rules>
<outboundRules>
<rule name="chat" preCondition="">
<match filterByTags="A, Area, Base, Form, Head, IFrame, Img, Input, Link, Script" pattern="chat/*" negate="false" />
<action type="Rewrite" value="http://127.0.0.1:5000" />
</rule>
</outboundRules>
</rewrite>
</system.webServer>
</configuration>
Anything I'm doing wrong? Thanks
Since this is a outbound rule, your client will receive the address as http://127.0.0.1:5000. Assuming the client machine has no application installed at port 5000, you will run into an error.
Try using a Inbound Rewrite rule (If you dont want the URL to change on the browser) or Inbound redirect rule (if you want the URL to change on the browser) with the same parameters and let the server do the talking.
On my development machine, I am trying to configure IIS as a reverse proxy to forward requests coming in port 443 to a nodejs application running locally.
The requests are getting forwarded fine, but sometimes the the nodejs application tries to redirect the browser to an external site and the IIS url rewrite module change that also to point to the local server.
I am accessing the site using https://localhost/test
IIS reroutes the requests to the node app http://localhost:14819/test
The node app returns an http 302 with location header set to https://example.com/someroute
IIS transforms this to https://localhost/someroute
I want the external urls to be untouched by IIS. How to do this?
Here is my Web.config content
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<clear />
<rule name="ReverseProxyInboundRule1" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^test(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_HOST}" pattern="^localhost" />
</conditions>
<action type="Rewrite" url="http://localhost:14819/test{R:1}" logRewrittenUrl="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
If you have any redirect coming back from the backend proxy and you do
not want to redirect the Location header coming ,You can do that by
unchecking "Reverse rewritehost in response headers" in Application
Request Routing
Select the server node in IIS manager
Go to Application Request routing Cache
Click on Server proxy Settings
UnCheck "Reverse rewritehost in response headers"
I have two separate websites on my server:
X:\Inetpub\wwwroot\MySite1\ and X:\Inetpub\wwwroot\MySite2.
I'm trying to set up some URL Rewrites, so I'm starting simple. I created a web.config file in X:\Inetpub\wwwroot\MySite1\web.config with the following code:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Contact" stopProcessing="true">
<match url="^contact$" />
<action type="Rewrite" url="/16_Contact.cfm" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
When someone enters the url "MySite1.com/contact", I want the browser to take them straight to "MySite1.com/16_Contact.cfm". But when I try it in a browser, I get a 404 error. I'm using an ancient version of Coldfusion (MX7), if that matters. Is there something obvious I'm missing?
It has been a while since I have used CF7, but I remember running into this issue, and it had something to do with the order in which CF and the rewrite module were added to the site in IIS.
First make sure your Coldfusion installation has the most recent patches, then try using the Web Server Configuration Tool that comes with Coldfusion to remove and re-add the Coldfusion modules/settings to your IIS site.
My IIS setup has one site, bound to a domain. Let's call it: www.mydomain.com
The site folder itself is empty. This site hosts multiple applications and virtual directories. One of the applications is 'portal'.
What I want to do is accept any incoming request for www.mydomain.com or www.mydomain.com/ and redirect it to: www.mydomain.com/portal
I've got ARR and URL Rewrites up and running. I'm just not sure how to configure them for this.
A redirection rule like below will work.
Put the following web.config file to your web site's root folder. Or, update the existing one if you have.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="toPortal" stopProcessing="true">
<match url="^$" />
<action type="Redirect" url="/portal" redirectType="Found" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
You may want look at this tutorial to learn how to create url rewrite rules with IIS Manager. These xml nodes are not coming from my brain too.