简体   繁体   English

强制React-Router应用将URL请求发送到服务器

[英]Force react-router app to send URL requests to server

I am developing a react app with react router with a server hosting both the react app itself and a REST API. 我正在开发带有React Router的React App,该Server托管着React App本身和REST API。 The router is ConnectedRouter from react-router-redux. 路由器是react-router-redux中的ConnectedRouter。 As I understand, once you have opened the app in your browser, any changes to the URL will not be requested from the server but instead handled client-side in react router, even if you reload the page or write something manually into the address bar. 据我了解,一旦您在浏览器中打开了应用程序,就不会从服务器请求对URL进行任何更改,而是会在React Router中处理客户端,即使您重新加载页面或在地址栏中手动写一些内容。

When first opening the app, the actual HTML, JS and CSS files are loaded from the web server, which is configured to only serve them if the user is authorized. 首次打开该应用程序时,实际的HTML,JS和CSS文件是从Web服务器加载的,该服务器配置为仅在授权用户的情况下才提供服务。 This way, the server can redirect the user to a third-party authentication site, or serve a 401 message if the user is authenticated but not authorized. 这样,服务器可以将用户重定向到第三方身份验证站点,或者在用户经过身份验证但未经授权的情况下提供401消息。 However, the problem occurs when the user session expires, he logs out or his permissions change so that he's no longer authorized to open the app. 但是,当用户会话过期,他注销或权限更改从而不再授权他打开应用程序时,就会发生问题。 Then when the user opens the app on a browser that has previously cached it, it appears to open as normal, but with lots of errors because every API call now fails. 然后,当用户在以前已缓存应用程序的浏览器中打开该应用程序时,它似乎可以正常打开,但是会出现很多错误,因为现在每个API调用都会失败。

To solve this I would like to, when the API calls fail, tell the user to reload the page so that a request is made to the server to fetch the app (index.html, etc), so that he gets redirected to the third party authentication site. 为了解决这个问题,我想在API调用失败时告诉用户重新加载页面,以便向服务器发出请求以获取应用程序(index.html等),以便将他重定向到第三个第三方认证站点。 However a regular browser reload (F5) doesn't cut it. 但是,常规的浏览器重新加载(F5)不会削减它。 The request is swallowed by react-router, and never hits the server. 该请求被react-router吞没,并且从未命中服务器。 This is also the case with window.location.reload(). window.location.reload()也是这种情况。 A hard reload, ie Ctrl+F5 seems to do the trick, at least in chrome, but some users may not understand that. 硬重载,即Ctrl + F5似乎可以解决问题,至少在chrome中是这样,但是有些用户可能不明白。 Thus I would like to present the user with a "hard reload" button that temporarily tells react-router to yield url requests, so that they can pass to the server and try to fetch index.html. 因此,我想为用户提供一个“硬重载”按钮,该按钮临时告诉react-router产生url请求,以便它们可以传递到服务器并尝试获取index.html。

So my question is: How can I temporarily and programatically force the client-side app to allow URL requests to go to the server as normal, as opposed to handling them itself in react-router? 所以我的问题是:我该如何临时性地以编程方式强制客户端应用程序允许URL请求正常发送到服务器,而不是在react-router中本身处理它们?

Alternatively, if this is not possible, how can I programatically purge the app from the browser's memory, so that it will be forced to request the server again? 或者,如果不可能,如何以编程方式从浏览器的内存中清除该应用程序,以使其被迫再次请求服务器?

Edit: It seems my assumption that the requests are swallowed by react-router was wrong. 编辑:似乎我的假设是,请求被react-router吞没了。 It was the service worker in the create-react-app framework. 它是create-react-app框架中的服务工作者。 The service worker exposes an unregister function that solved my problem. 服务人员公开了一个注销功能,该功能解决了我的问题。

As I understand, once you have opened the app in your browser, any changes to the URL will not be requested from the server but instead handled client-side in react router, even if you reload the page or write something manually into the address bar. 据我了解,一旦您在浏览器中打开了应用程序,就不会从服务器请求对URL进行任何更改,而是会在React Router中处理客户端,即使您重新加载页面或在地址栏中手动写一些内容。

This is not true. 这不是真的。 Upon manual change in address bar (and pressing enter), you will always first hit server router. 手动更改地址栏中的内容(并按Enter键)后,您始终始终会先点击服务器路由器。

It is very likely that your server, no matter which url is hit, will always render your index.html which contains your React app. 无论命中哪个URL,您的服务器很可能始终呈现包含React应用程序的index.html Something similar to this: 类似于以下内容:

app.use(express.static(path.join(__dirname, 'dist')));
app.get('*', function(req, res) {
    res.sendfile('./dist/index.html');
});

Make sure your API requests do not conflict with this. 确保您的API请求与此不冲突。 If possible, share some code, so we can review what could go wrong. 如果可能,请共享一些代码,以便我们可以回顾可能出现的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM