I am working on SPA application using Angularjs and .Net's web api. It all seems to work, in ability to refresh my pages I have added rules to my web.config file as follows and they all work except one, when I refresh detail page that has a parmeter, something like this http://domain/traveldetail/135. Please advise how should I approach this:
Web.config's rewrite section:
<rewrite>
<rules>
<rule name="TravelList" stopProcessing="true">
<match url="^travellist" />
<action type="Rewrite" url="/" />
</rule>
<rule name="TravelDetail" stopProcessing="true"> <!--NOT WORKING-->
<match url="^traveldetail/:travelId" />
<action type="Rewrite" url="/" />
</rule>
<rule name="AdvancedSearch" stopProcessing="true">
<match url="^advancedsearch" />
<action type="Rewrite" url="/" />
</rule>
<rule name="CreditCardMatcher" stopProcessing="true">
<match url="^creditcardmatcher" />
<action type="Rewrite" url="/" />
</rule>
<rule name="ApprovalGroups" stopProcessing="true">
<match url="^approvalgroups" />
<action type="Rewrite" url="/" />
</rule>
<rule name="Help" stopProcessing="true">
<match url="^help" />
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
It's not working because the :travelId in url="^traveldetail/:travelId" is the parameter notation for AngularJS and not a valid regular expression.
Change it for something like this: url="^traveldetail/(.+)", and it should work.
Related
Pay attention to the following examples.
subdomain1.sample.com => target.sample.com/1001
subdomain1.sample.com/order => target.sample.com/1001/order
subdomain1.sample.com/login => target.sample.com/1001/login
subdomain2.sample.com => target.sample.com/1002
subdomain2.sample.com/order => target.sample.com/1002/order
subdomain2.sample.com/login => target.sample.com/1002/login
A reactjs project is running on target.sample.com, which is as follows
/ ==> page not found
/:id ==> home
/:id/login ==> page login
/:id/order ==> page order
We want to do this in IIS with the help of proxy reverse or rewrite.
Below are the settings of the web.config file related to the subdomain1.sample.com address
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="http_to_https" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" appendQueryString="false" />
</rule>
<rule name="proxy" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="https://target.sample.com/1001/{R:1}" />
</rule>
</rules>
<outboundRules>
<rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsHtml1">
<match filterByTags="A, Form, Img" pattern="^https://target.sample.com/1001/(.*)" />
<action type="Rewrite" value="https://subdomain1.sample.com/{R:1}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" path="https://{HTTP_HOST}{REQUEST_URI}" responseMode="ExecuteURL" />
</httpErrors>
</system.webServer>
</configuration>
such an error can be seen in the browser console
Uncaught SyntaxError: Unexpected token '<' (at main.697bcedd.js:1:1)
Have I gone the wrong way? How can I solve this problem?
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>
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"
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>
I have created Angularjs app and hosted in an IIS server. I used prerender.io for SEO and it works really well.
But I have a problem with sharing my web site on facebook. It gives me following errors when I try on facebook debugging tool.
https://developers.facebook.com/tools/debug
web.conf
<rule name="RemoveTrailingSlash" stopProcessing="true">
<match url="(.*)/$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Redirect" redirectType="Permanent" url="{R:1}" />
</rule>
<rule name="HotelRedirectRulesLenon1" patternSyntax="ECMAScript" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_HOST}" pattern="^example.(com|net|com.au)$" />
</conditions>
<action type="Redirect" url="http://www.example.org" />
</rule>
<rule name="HotelRedirectRulesLenon2" patternSyntax="ECMAScript" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_HOST}" pattern="^www.example.(com.au)$" />
</conditions>
<action type="Redirect" url="http://www.example.org/{R:0}" />
</rule>
<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="/index.html" />
</rule>
<rule name="Prerender" stopProcessing="true">
<match url="^(?!.*?(\.js|\.css|\.xml|\.less|\.png|\.jpg|\.jpeg|\.gif|\.pdf|\.doc|\.txt|\.ico|\.rss|\.zip|\.mp3|\.rar|\.exe|\.wmv|\.doc|\.avi|\.ppt|\.mpg|\.mpeg|\.tif|\.wav|\.mov|\.psd|\.ai|\.xls|\.mp4|\.m4a|\.swf|\.dat|\.dmg|\.iso|\.flv|\.m4v|\.torrent))(.*)" ignoreCase="false" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_USER_AGENT}" pattern="baiduspider|facebookexternalhit|twitterbot" />
<add input="{QUERY_STRING}" pattern="_escaped_fragment_" ignoreCase="false" />
</conditions>
<action type="Rewrite" url="http://example/{R:2}" />
</rule>
I responded to your email but wanted to respond here too in case anyone else has similar issues.
First, You shouldn't be doing a 301 redirect to http://service.prerender.io/. The proxy should happen behind the scenes so that the crawler has no idea you are using Prerender.io. If you 301 redirect, you are telling the crawler that you should send users to our service and that is incorrect.
Also, you are setting window.prerenderReady = false and never setting it to true so that means we are going to wait until we hit our timeout to return the page. That's causing Facebook to timeout.