【问题标题】:ReactJS - Is it possible to replace item in browser history?ReactJS - 是否可以替换浏览器历史记录中的项目?
【发布时间】:2021-12-02 22:29:59
【问题描述】:

我这里有这行代码:

if(window.location.search == "?mytoken=abc") {
          window.history.replaceState(null, '', window.location.pathname);
}

此代码的作用是检查查询参数 mytoken 是否存在,如果存在,则替换没有查询参数的当前页面,这样可以完美运行。

但我确实注意到我的浏览器历史记录中确实有 2 个历史记录项,一个带有查询参数,另一个没有查询参数。我正在寻找从浏览器历史记录中删除带有查询参数的项目。这可能吗?

我在我的项目中找到了这段代码,如果有帮助的话:

history.listen((newLocation, action) => {

      if (action === "PUSH") {
        if (
          newLocation.pathname !== this.currentPathname ||
          newLocation.search !== this.currentSearch
        ) {
          // Save new location
          this.currentPathname = newLocation.pathname;
          this.currentSearch = newLocation.search;

          // Clone location object and push it to history
          history.push({
            pathname: newLocation.pathname,
            search: newLocation.search,
          });
        }
      } else {
        // Send user back if they try to navigate back
        history.go(1);
      }
    });

每次出现新页面时都会调用它。

【问题讨论】:

  • 无法删除或修改过去的浏览器历史记录状态,但您可以使用自己的自定义对象来模拟历史记录,您可以完全控制这些状态。请查看the top answer here 以获取此方法的示例

标签: reactjs


【解决方案1】:

你可以在javascript中使用new URL See Docs

const url = new URL(YOUR_URL);

您可以访问 url

的所有部分
consr origin = url.origin; // domain.com
const pathname = url.pathname; // /path/test
const search = url.search; // ?query=true

window.location.replace = url.origin + url.pathname + url.search;

history.replace({
    pathname: url.pathname,
    search: url.search
});

您也可以在App.js 中使用useEffect

import { useEffect } from 'react';
import { useLocation, useHistory } from 'react-router-dom';

const Component = () => {
    const { pathname, search } = useLocation();
    const hidtory = useHistory();

    useEffect(() => {
        if (search === "..." || pathnamr === "...") {
            history.replace({...});
        }
    }, [pathname, search]);
}

【讨论】:

    【解决方案2】:

    有一种相关技术可以从浏览器历史记录中删除 SPA 的登录响应中收到的 OAuth 字段 - 请参阅 this code of mine 中的 history.replaceState 调用并检查它是否适合您。

    private async handleLoginResponse(): Promise<void> {
    
        // Ask the security library to process the OAuth response    
        const user = await this.userManager.signinRedirectCallback();
    
        // Return to the app location before the login redirect
        const preRedirectLocation = user.state.hash;
    
        // Remove OAuth details from back navigation
        history.replaceState({}, document.title, preRedirectLocation);
    }
    

    在我的情况下,删除的值是 authorization code,我想从 URL 中删除这些安全详细信息:

    https://www.example.com?code=7890257802&state=807245780
    

    请注意,URL 中的标记也可能最终出现在 Web 服务器日志中。因此,URL 中的任何标记都应为 one time use,授权码也是如此。

    【讨论】:

      【解决方案3】:

      我建议使用 pushState api。此 api 在当前条目之后删除浏览上下文的会话历史记录中的所有条目。如果当前条目是会话历史中的最后一个条目,则不会删除任何条目。 因此,当您尝试替换 url 时,您可以 pushState 删除当前 URL,并推送新 URL。

      稍后我会写一个解决方案,但上面的 api 将是一个很好的开始提示。

      【讨论】:

        【解决方案4】:

        是的!你可以用history.replace代替history.push

        history.replace({
           pathname: newLocation.pathname,
           search: newLocation.search,
        });
        

        P.S:不是 window.history。 npm install --save history

        参考:https://github.com/remix-run/history/blob/main/docs/api-reference.md#history.replace

        【讨论】:

          猜你喜欢
          • 2017-01-11
          • 1970-01-01
          • 2017-11-04
          • 1970-01-01
          • 2011-04-05
          • 2015-06-14
          • 1970-01-01
          • 1970-01-01
          • 2017-08-17
          相关资源
          最近更新 更多