Pah*_*iya 41 javascript single-page-application reactjs
在基于服务器端的完全呈现(非Web 2.0)中,部署服务器端代码将在页面重新加载时直接更新客户端页面.相比之下,在基于React的单页应用程序中,即使在更新了React组件之后,仍然会有一些客户端使用旧版本的组件(它们仅在浏览器重新加载时获得新版本,这应该很少发生) - >如果页面完全是SPA,有些客户可能会在几个小时后刷新页面.
应采用哪些技术来确保任何客户不再使用旧组件版本?
更新:API未更改,只有更新版本更新了React组件.
haz*_*ous 42
在应用程序加载时,您可以让React组件向服务器发出ajax请求,以获取"接口版本".在服务器API中,您可以维护客户端版本的增量值.React组件可以将此值存储在客户端(cookie /本地存储/等)上.当它检测到更改时,它可以调用window.location.reload(true);哪个应该强制浏览器丢弃客户端缓存并重新加载SPA.或者更好的是,通知最终用户将加载新版本并询问他们是否希望保存工作然后重新加载等取决于您想要做什么.
与史蒂夫泰勒的答案类似,但不是版本化API端点,而是按照以下方式对客户端应用程序进行版本控制.
每个HTTP请求都会发送一个自定义标头,例如:
X-Client-Version: 1.0.0
然后,服务器将能够拦截这样的头部并相应地做出响应.
如果服务器知道客户端的版本是陈旧的,例如,如果当前版本是1.1.0,则使用将由客户端适当处理的HTTP状态代码进行响应,例如:
418 - I'm a Teapot
然后可以通过以下方式对客户端进行编程以通过刷新应用程序来响应此类响应:
window.location.reload(true)
基本前提是服务器知道最新的客户端版本.
编辑:
您可以将应用程序的版本与来自 API 任何端点的每个响应一起发送。因此,当应用程序发出任何 API 请求时,您可以轻松检查是否有新版本,并且您需要重新加载。如果 API 响应中的版本比 localStorage 中存储的版本新,则设置window.updateRequired = true. 您可以拥有以下包装react-router's 的反应组件Link:
import React from 'react';
import { Link, browserHistory } from 'react-router';
const CustomLink = ({ to, onClick, ...otherProps }) => (
  <Link
    to={to}
    onClick={e => {
      e.preventDefault();
      if (window.updateRequired) return (window.location = to);
      return browserHistory.push(to);
    }}
    {...otherProps}
  />
);
export default CustomLink;
并Link在整个应用程序中使用它而不是 react-router 。因此,每当有更新并且用户导航到另一个页面时,都会进行硬重新加载,用户将获得最新版本的应用程序。
您还可以显示一个弹出窗口:“有更新,单击 [此处] 以启用它。” 如果您只有一页或您的用户很少浏览。或者无需询问即可重新加载应用程序。这取决于您的应用程序和用户。
应该采用什么技术来确保任何客户端不再使用旧组件版本?
今天(2018 年),很多前端应用都使用了Service Worker。有了它,可以通过多种方式管理您的应用程序生命周期。
这是第一个示例,通过使用 ui 通知,要求您的访问者刷新网页以获取最新的应用程序版本。
import * as SnackBar from 'node-snackbar';
// ....
// Service Worker
// https://github.com/GoogleChrome/sw-precache/blob/master/demo/app/js/service-worker-registration.js
const offlineMsg = 'Vous êtes passé(e) en mode déconnecté.';
const onlineMsg = 'Vous êtes de nouveau connecté(e).';
const redundantMsg = 'SW : The installing service worker became redundant.';
const errorMsg = 'SW : Error during service worker registration : ';
const refreshMsg = 'Du nouveau contenu est disponible sur le site, vous pouvez y accéder en rafraichissant cette page.';
const availableMsg = 'SW : Content is now available offline.';
const close = 'Fermer';
const refresh = 'Rafraîchir';
if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    function updateOnlineStatus() {
      SnackBar.show({
        text: navigator.onLine ? onlineMsg : offlineMsg,
        backgroundColor: '#000000',
        actionText: close,
      });
    }
    window.addEventListener('online', updateOnlineStatus);
    window.addEventListener('offline', updateOnlineStatus);
    navigator.serviceWorker.register('sw.js').then((reg) => {
      reg.onupdatefound = () => {
        const installingWorker = reg.installing;
        installingWorker.onstatechange = () => {
          switch (installingWorker.state) {
            case 'installed':
              if (navigator.serviceWorker.controller) {
                SnackBar.show({
                  text: refreshMsg,
                  backgroundColor: '#000000',
                  actionText: refresh,
                  onActionClick: () => { location.reload(); },
                });
              } else {
                console.info(availableMsg);
              }
              break;
            case 'redundant':
              console.info(redundantMsg);
              break;
            default:
              break;
          }
        };
      };
    }).catch((e) => {
      console.error(errorMsg, e);
    });
  });
}
// ....
还有一种优雅的方法可以在后台检查升级,然后在用户单击内部链接时静默升级应用程序。该方法呈现在ach.codes和讨论在此线程以及
| 归档时间: | 
 | 
| 查看次数: | 21790 次 | 
| 最近记录: |