How to display 404 when URL doesn't match any

2020-08-10 07:44发布

This is my first time using ReactJS and is not my project however, I am trying to redirect any non-existent routes to a 404 page that I have made. My 404 page is currently displaying as intended when any URL that doesn't match a route is entered apart from when the URL contains /#/.

For example, this URL will redirect to my 404 page:

http://localhost:8080/non-existent-url

But this URL will only load my app's default route (homepage):

http://localhost:8080/#/non-existent-url

I don't know what the /#/ is for and it appears that the app will display pages with valid routes with or without it.

Stripped down routes file:

import React from "react";
import { Router, Route, IndexRoute, browserHistory, hashHistory, Redirect } from "react-router/es";
import willTransitionTo from "./routerTransition";
import App from "./App";
import DashboardContainer from "./components/Dashboard/DashboardContainer";
import DashboardAccountsOnly from "./components/Dashboard/DashboardAccountsOnly";
import NotFound from './components/NotFound';

const history = __HASH_HISTORY__ ? hashHistory : browserHistory;

class Auth extends React.Component {
    render() {return null; }
}

const routes = (
    <Route path="/" component={App} onEnter={willTransitionTo}>
        <IndexRoute component={DashboardContainer}/>
        <Route path="/auth/:data" component={Auth}/>
        <Route path="/dashboard" component={DashboardContainer}/>

        <Route path='*' exact={true} component={NotFound} />
    </Route>
);

export default class Routes extends React.Component {
    render() {
        return <Router history={history} routes={routes} />;
    }
}

404 (NotFound) component:

import React from 'react';
import {Link} from "react-router/es";
import Translate from "react-translate-component";

var image = require("assets/404.png");

const NotFound = () =>

    <div className="grid-block main-content wrap regular-padding">
        <div className="grid-content small-12" style={{marginTop:"200px"}}>
            <div style={{ textAlign:"center"}}>
                <img style={{marginBottom:"1.2rem"}} src={image} />
                <h3>404 page not found</h3>
                <p>This page does not exist.</p>
                <Link className="button" to={"/dashboard"}>
                    <Translate style={{color:"#fff"}} content="account.home" />
                </Link>
            </div>
        </div>
    </div>

export default NotFound;

How can I redirect users to my 404 page when a URL doesn't match any route and when the URL contains /#/?

7条回答
叛逆
2楼-- · 2020-08-10 08:08

You can access the location.hash value and set it to blank.

But as already well described, this is standard http for years and you shouldn't care except for a good reason.

You can see it like http://localhost:8080/?non-existent-url it means go to / with path parameter non-existent-url do you want to redirect too ?

查看更多
等我变得足够好
3楼-- · 2020-08-10 08:15

There are few unsafe characters which should be avoided while creating URL one of them is #.

The character “#” is unsafe and should always be encoded because it is used in World Wide Web and in other systems to delimit a URL from a fragment/anchor identifier that might follow it.

Server while resolving the route will pass the string before # to get the page requested and then it will be moved the exact fragment of page if anything specifed using the string after # till any unsafe character.

So, In your string before # is empty that's why it redirect to / which is a valid route and it redirect to component App. And since no fragment is defined that's why nothing happening.

To make this works we need to tell nginx or any other server to strip down all the # before sending request forward.

In that case,

http://localhost:8080/#/non-existent-url

will be converted to,

http://localhost:8080/non-existent-url

Which will solve the issue. See this link to see How to rewrite rule in nginx

查看更多
冷血范
4楼-- · 2020-08-10 08:17

For react-router < 4.0

If you want to display an error page and not change the path

<Route path='*' exact={true} component={errorcomponent} />

If you want to display an error page and change the path

<Route path='/error' component={errorcomponent} />
 // use redirect to  change the Url
<Redirect from='*' to='/error' />

For react-router 4

Keep the path

<Switch>
    <Route exact path="/" component={component} />
    <Route component={errorcomponent} />
 </Switch>

change Url.

 <Switch>
    <Route path="/comp" component={component} />
   <Redirect to="/error" />
 </Switch>

the redirect tag has to be put whereever you place a route tag insde a switch.

查看更多
闹够了就滚
5楼-- · 2020-08-10 08:17

You can use this

<Route exact insecure component={NotFound} />
查看更多
\"骚年 ilove
6楼-- · 2020-08-10 08:26

you should Router component as parent of your Routes and add this Route

<Route path='*' component={() => NotFound} />

const routes = (
    <Router>
        <div>
            <Route path="/" component={App} onEnter={willTransitionTo}
            <IndexRoute component={DashboardContainer}/>
            <Route path="/auth/:data" component={Auth}/>
            <Route path="/dashboard" component={DashboardContainer}/>

            <Route path='*' component={() => NotFound} />
        </div>
    </Router>
);
查看更多
干净又极端
7楼-- · 2020-08-10 08:32

Based on what I'm seeing in your code, trying to switch between hash history and browser history just isn't going to work. The moment you hit '/#' in anything it's going to break and always hit your generic '/' route.

Hash URLs are an older way of handling things that shouldn't be an issue anymore. See this SO question and its accepted answer for more details.

Doing links like Twitter, Hash-Bang #! URL's

So yeah, unless you have some crazy reason to still support hashes in URLs, drop hash history and simply use browser history. Then your routes as defined in your provided code sample should work.

查看更多
登录 后发表回答