React-router urls don't work when refreshing o

2018-12-31 02:49发布

I'm using React-router and it works fine while I'm clicking into link buttons, but when I refresh my webpage it does not load what I want.

For instance, I am into localhost/joblist and everything is fine because I arrived here pressing a link. But If I refresh the webpage I get: Cannot GET /joblist

By default It didn't work like this. Initially I had my URL: localhost/#/ and localhost/#/joblist and they worked perfectly fine. But I don't like this kind of url, so trying to erase that '#' I wrote:

Router.run(routes, Router.HistoryLocation, function (Handler) {
 React.render(<Handler/>, document.body);
});

This problem does not happen with localhost/, this one always returns what I want.

EDIT: This app is single-page, so /joblist don't need to ask anything to any server.

EDIT2: My entire router.

var routes = (
    <Route name="app" path="/" handler={App}>
        <Route name="joblist" path="/joblist" handler={JobList}/>
        <DefaultRoute handler={Dashboard}/>
        <NotFoundRoute handler={NotFound}/>
    </Route>
);

Router.run(routes, Router.HistoryLocation, function (Handler) {
  React.render(<Handler/>, document.body);
});

28条回答
萌妹纸的霸气范
2楼-- · 2018-12-31 02:56

I like this way of handling it. Try adding: yourSPAPageRoute/* on the server side to get rid of this problem.

I went with this approach because even the native HTML5 History API doesn't support correct redirection on page refresh (As far as I know).

Note: Selected answer has already addressed this but I'm trying to be more specific.

Express Route

Test - History API Tested and just wanted to share this.

Hope it helps.

查看更多
忆尘夕之涩
3楼-- · 2018-12-31 02:57

If you're hosting a react app via AWS Static S3 Hosting & CloudFront

This problem presented itself by CloudFront responding with a 403 Access Denied message because it expected /some/other/path to exist in my S3 folder, but that path only exists internally in React's routing with react-router.

The solution was to set up a distribution Error Pages rule. Go to the CloudFront settings and choose your distribution. Next go to the "Error Pages" tab. Click "Create Custom Error Response" and add an entry for 403 since that's the error status code we get. Set the Response Page Path to /index.html and the status code to 200. The end result astonishes me with its simplicity. The index page is served, but the URL is preserved in the browser, so once the react app loads, it detects the URL path and navigates to the desired route.

Error Pages 403 Rule

查看更多
宁负流年不负卿
4楼-- · 2018-12-31 02:57

If you are using Create React App:

There's a great walk though of this issue with solutions for many major hosting platforms that you can find HERE on the Create React App page. For example, I use React Router v4 and Netlify for my frontend code. All it took was adding 1 file to my public folder ("_redirects") and one line of code in that file:

/*  /index.html  200

Now my website properly renders paths like mysite.com/pricing when entered into the browser or when someone hits refresh.

查看更多
浮光初槿花落
5楼-- · 2018-12-31 02:57

If you are hosting in IIS ; Adding this to my webconfig solved my problem

    <httpErrors errorMode="Custom" defaultResponseMode="ExecuteURL">
        <remove statusCode="500" subStatusCode="100" />
        <remove statusCode="500" subStatusCode="-1" />
        <remove statusCode="404" subStatusCode="-1" />
        <error statusCode="404" path="/" responseMode="ExecuteURL" />
        <error statusCode="500" prefixLanguageFilePath="" path="/error_500.asp" responseMode="ExecuteURL" />
        <error statusCode="500" subStatusCode="100" path="/error_500.asp" responseMode="ExecuteURL" />
    </httpErrors>

You can make similar configuration for any other server

查看更多
看淡一切
6楼-- · 2018-12-31 02:58

add this to webpack.congif.js

devServer: {
      historyApiFallback: true
  }
查看更多
唯独是你
7楼-- · 2018-12-31 02:58

If you're using firebase all you have to do is make sure you've got a rewrites property in your firebase.json file in the root of your app (in the hosting section).

For example:

{ 
  "hosting": {
    "rewrites": [{
      "source":"**",
      "destination": "/index.html"
    }]    
  }
}

Hope this saves somebody else a hoard of frustration and wasted time.

Happy coding...

Further reading on the subject:

https://firebase.google.com/docs/hosting/full-config#rewrites

Firebase CLI: "Configure as a single-page app (rewrite all urls to /index.html)"

查看更多
登录 后发表回答