ReactJS - 是不是可以替换浏览器历史记录中的项目?

Posted

技术标签:

【中文标题】ReactJS - 是不是可以替换浏览器历史记录中的项目?【英文标题】: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 以获取此方法的示例 【参考方案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

【讨论】:

以上是关于ReactJS - 是不是可以替换浏览器历史记录中的项目?的主要内容,如果未能解决你的问题,请参考以下文章

用javascript 怎样清空访问过的锚点记录

历史推送和替换之间的权衡是啥?

如何从 git 历史记录中的文件中替换文本?

Angular 2 - 替换历史而不是推送

React-router:更改 URL 并清除历史记录

重定向到新网址,但从历史记录中删除以前的网址