I have a React App hosted on IIS. If I access an existing directory, such as <app_url>/static/, it returns a 403 response since there's no permission on that directory. I'd like to redirect the user to my root page (~/).
I have tried this:
<httpErrors>
<remove statusCode="403" subStatusCode="-1" />
<error statusCode="403" prefixLanguageFilePath="" path="/" responseMode="ExecuteURL" />
</httpErrors>
This kinda works, it does return the root page, however, it tries to download the React bundles from /static/ instead of '/' only.
What can I do here?
I used this rule and it worked:
<rewrite>
<rules>
<rule name="Redirect Static" patternSyntax="ExactMatch" stopProcessing="true">
<match url="static" />
<action type="Redirect" url="/" redirectType="Found" />
</rule>
</rules>
</rewrite>
(Thanks to #samwu)
Related
I have a web.config in my React application (imported in index.tsx):
<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" />
</conditions>
<action type="Rewrite" url="index.html" />
</rule>
</rules>
</rewrite>
<staticContent>
<remove fileExtension=".json" />
<remove fileExtension=".woff2" />
<remove fileExtension=".png" />
<remove fileExtension=".svg" />
<remove fileExtension=".ico" />
<remove fileExtension=".webmanifest" />
<mimeMap fileExtension=".json" mimeType="application/json" />
<mimeMap fileExtension=".woff2" mimeType="font/woff2" />
<mimeMap fileExtension=".png" mimeType="image/png" />
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
<mimeMap fileExtension=".ico" mimeType="image/vnd.microsoft.icon" />
<mimeMap fileExtension=".webmanifest" mimeType="application/manifest+json" />
</staticContent>
</system.webServer>
</configuration>
The application is served on a subdomain (https://example.com/app/) and if I try to go to a subroute (like https://example.com/app/page1) which works perfectly fine in development mode, returns a page not found error on the server.
What am I doing wrong?
Since you provided less error message, I can only share some of my thoughts with you. My expression may not be accurate enough, hope you can understand my weak English.
Once you have a production build of your ReactJS application. It creates an index.html file that serves the entire application. All requests must be index.html first, and then React Router serves the content based on the query in the URL. When we access the app using the main URL, it hits index.html and works fine. If you go directly to a sub URL in your browser, the web server cannot find any file with that name. In this case, a 404 error message will be returned to the user.
Due to the update after version 6.0, the parent route must add /* , otherwise it will not navigate deeper, the parent route will no longer match, so the child route will never be rendered.
<Route path="/home" element={<Home/>}></Route>
change to
<Route path="/home/*" element={<Home/>}></Route>
If you expect all routes to be defined by React Router, only your backend, no matter what route, returns index.html. The rest is left to React Router. Then all you have to do is modify the backend server. If using HashRouter, change BrowserRouter to HashRouter. In this way, all requests will be directed to the index.html page, and the server side does not need any configuration.
In addition, the child routing page refreshes and reports an error, and normal access from the parent does not report an error. The reason may be that the js import path in the main file index.html is written as an absolute path; it needs to be imported by a relative path, or the address of a js file imported is wrong and needs to be checked.
I share with you a thread, it provides a very detailed explanation and potential solution.
When I try to do a GET call to a subroute of my react application I get a 404.
When I do this to my homepage it returns correctly the HTML.
When just accessing the subroutes via the browser my webpage gets correctly rendered.
I'm Using React version 16.9.0.
I'm hosting the web application in Azure App service.
The reason for this question is to use an external program that can check for deadlinks in a website. At the moment I get 404's for every call to a subroute.
GET calls in Postman:
www.test.be => works
www.test.be/custom-route => gives a 404
This is my React Router Wrapper component:
import React from 'react';
import { Switch, Route } from 'react-router-dom';
import Home from 'home/containers/home-container.js';
import NotFoundPage from './error-pages/not-found-page';
import Questions from 'questions/containers/question-container.js';
const Body = () => {
return (
<Switch>
<Route path="/" exact component={Home} />
<Route path="/questions" component={Questions} />
<Route component={NotFoundPage} />
</Switch>
);
};
export default Body;
This is my web.config file:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<httpRuntime requestPathInvalidCharacters="<,>,*,&,:,\\,?" />
</system.web>
<system.webServer>
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By" />
</customHeaders>
</httpProtocol>
<rewrite>
<rules>
<rule name="HTTPSs">
<match url="(.*)"/>
<conditions>
<add input="{HTTPS}" pattern="Off"/>
<add input="{HTTP_HOST}" negate="true" pattern="^localhost" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}"/>
</rule>
<rule name="ReactRoutes" 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>
<security>
<requestFiltering allowDoubleEscaping="true"/>
</security>
</system.webServer>
</configuration>
You don't provide complete details but If I understand correctly, it can help you to solve your problem, if you have this problem on the server and when you open the homepage it works correctly and when open a subroute it goes to 404 page, add this to your .htaccess file
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
This is because how reactjs applications gets deployed on your production WebServer.
Reactjs applications are served deployed on with single index.html. Entire entire react project is served from index.html (This is how 'www.test.be' works). React-router programmatically updates the browser URL based on which page you navigate.
When your visit 'www.test.be/custom-url', the request is first caught and processed by the webserver. The webserver is expecting HTML file named 'custom-url.html' doesn't find it. So webserver throws a '404' i.e. 'Page not found' error. The request is not forwarded to your ReactApp - so your ReactApp never gets a chance to process the request.
The solution depends on the type of hosting service you are using. Basically, you want to redirect all URLs to React App (index.html) so that React Application will get a chance to process 404.
Update your question with the hosting service you are using (such as netlify, heroku, aws etc) and I can update this answer with a solution suitable for that hosting service.
For instance, if the webhost is netlify, you can create a file called _redirect in public/ directory with the following content
/* /index.html 200
That will redirect all traffic (*) to index.html
It happens because you don't have SSR (Server-Side Rendering). probably you're using CRA to create your ReactJs web application, so it works with CSR and the sub-routes couldn't be understood by server.
I don't mean bring SSR to your project, because you should be serious about using SSR for some special reasons. by the way, there is a very simple solutions for any kind of servers, you should redirect all requests to the index.html then react-router can understand the sub-route in the client:
Redirect all to index.html:
PM2 server:
pm2 start [path-to-build-folder/app.js] --spa
Serve:
serve -s [path-to-build-folder/app.js]
IIS:
<!--web.config url rewrite-->
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Redirect To Index" stopProcessing="true">
<match url=".*" />
<conditions>
<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>
I don't know how you deployed your ReactJs web application, because some time DevOps specialist use running ReactJs app by using serve, pm2 or node under a special port for example: 8008 then by using IIS proxy try to connect the web application to local process, so by calling the port 80 user will be able to see the website. Also, you can directly serve the application by serving index.html in the IIS, and totally your solution is redirecting all requests to index.html.
Hope this answer helps you.
try this web.config :)
<?xml version="1.0" encoding="utf-8"?>
<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 have reactjs application with react router. I dont want to use hash history and I encountered the issue with refreshing page creating 404 error (react-router is not loaded when refreshing and browser wants to fetch non-existent content thus 404). I found some solution and I want to redirect every request to root so server always fetch index.html with import tags first.
My folder structure is simple:
ROOT/
-- index.html
-- static/
-- js/
-- main.js
-- css/
etc...
I have this web.config rule found on this site:
<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>
This works very fine with URLs on first folder path, I mean all request like /items, /contact are good. But requests like /items/detail are broken because browser is looking into items folder and not into document root. Also very important thing is that my webpack generate index.html script tags in this manner: <script type="text/javascript" src="./static/js/main.js">.
Is it possible that src attribute is wrong because of that ./? How can I tell server (IIS 10) "hey don't look anywhere else but into document root?"
Thanks guys.
This is a solution I found were I have some paths I still want to handle by my IIS but the rest I want react to take care.
<configuration>
<system.webServer>
<rewrite>
<rewriteMaps>
<rewriteMap name="^(.*)$" />
</rewriteMaps>
<rules>
<rule
name="redirect all requests"
stopProcessing="true"
>
<match url="^(.*)$" />
<conditions logicalGrouping="MatchAll">
<add
input="{REQUEST_URI}"
pattern="/someOtherResourceIstillWantIIStoHandle(.*)$"
negate="true"
/>
<add
input="{REQUEST_FILENAME}"
matchType="IsFile"
negate="true"
/>
<add
input="{REQUEST_URI}"
pattern="/resourcecentre(.*)$"
negate="true"
/>
</conditions>
<action type="Rewrite" url="/index.html" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
I am setting up a web.config in wwwroot to redirect all requests to index.html for angularjs to handle. This excludes existing files and folders and anything from /api.
The problem is, it's not working that way. I simply get blank pages for anything where a file does not exist.
Here is my web.config:
<configuration>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<handlers>
<add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified"/>
</handlers>
<httpPlatform processPath="%DNX_PATH%" arguments="%DNX_ARGS%" stdoutLogEnabled="false" startupTimeLimit="3600"/>
<rewrite>
<rules>
<rule name="IndexHomeRule" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/>
<add input="{REQUEST_URI}" matchType="Pattern" pattern="^/api/" negate="true" />
</conditions>
<action type="Rewrite" url="/index.html" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
I can't figure out any reason for it to still be trying to load the files instead of redirecting them to index.html
I am using .NET Core RC2 and I have static files and default files set to be used. I am using VS2015. I set the project up as a WebAPI from the beginning. Not empty.
You can use Microsoft.AspNetCore.SpaServices:
app.UseMvc(options =>
{
options.MapRoute("Api",
template: "api/{controller}/{action?}/{*path}",
defaults: new { controller = "Home" });
options.MapSpaFallbackRoute("spa-fallback", new { controller = "Home", action = "Index" });
});
When I browse to localhost/admin/videos/view/1 I get the page I want. I also want that page to show when I browse to localhost/videos/view/1.
But it gives me error message :
HTTP Error 404.0 - Not Found
Detailed Error Information:
Module IIS Web Core
Notification MapRequestHandler
Handler StaticFile
Error Code 0x80070002
Requested URL http://{my-ip}/app/webroot/videos/view/1
Physical Path C:\inetpub\wwwroot\{my-project}\app\webroot\videos\view\1
Logon Method Anonymous
Logon User Anonymous
These are my rules in the web.config file :
<rule name="Rewrite requests to test.php" stopProcessing="true">
<match url="^test.php(.*)$" ignoreCase="false" />
<action type="Rewrite" url="app/webroot/test.php{R:1}" />
</rule>
<rule name="Exclude direct access to app/webroot/*" stopProcessing="true">
<match url="^app/webroot/(.*)$" ignoreCase="false" />
<action type="None" />
</rule>
<rule name="Rewrite routed access to assets(img, css, files, js, fonts, vid, favicon)" stopProcessing="true">
<match url="^(img|css|files|js|fonts|vid|favicon.ico)(.*)$" />
<action type="Rewrite" url="app/webroot/{R:1}{R:2}" appendQueryString="false" />
</rule>
<rule name="Rewrite requested file/folder to index.php" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<action type="Rewrite" url="index.php" appendQueryString="true" />
</rule>
Update :
It has something to do with
<match url="^(img|css|files|js|fonts|vid|favicon.ico)(.*)$" />
When I cut the vid| (that is the directory of my videos) it shows localhost/videos/view/1.
But then I have the problem that it doesn't load my video.
What I've done to resolve this:
1 I deleted the |vid inside
<match url="^(img|css|files|js|fonts|favicon.ico)(.*)$" />
2 I replaced the vid folder inside my webroot to the files folder because that folder is standard there.
3 I changed the src to the video in my view
<source src="/files/vid/...