JS中浏览器历史记录的第二个不需要的电话

发布于 2025-01-19 02:53:17 字数 1211 浏览 3 评论 0原文

在我的应用程序中,我需要使用从 此包browserHistory 进行重定向>。为了传递一些上下文,我需要向 URL 添加一个查询字符串。我接收这些参数的格式是 JSON。因此,在能够调用 history.push 之前,我首先需要对给定的 JSON 进行字符串化和编码。

这是一个示例:

import { createBrowserHistory } from 'history';

const browserHistory = createBrowserHistory({ window });

const given = { x: 1 };

browserHistory.push(`/foo?test-param=${encodeURIComponent(JSON.stringify(given))}`);

此重定向有效...但它破坏了本机浏览器后退按钮(某种程度上)。您会看到,encodeURIComponent(JSON.stringify(given)) 输出 %7B%22x%22%3A1%7D。浏览器一看到 %3A 部分,就会自动将其更改为 URL 栏中的 :。这会导致 browserHistory 发生额外更改,这意味着发生了两次 URL 更改:

  1. /foo?test-param=%7B%22x%22%3A1%7D 这是上述代码
  2. /foo?test-param=%7B%22x%22:1%7D 生成的所需结果由浏览器自动完成(解码 %3A

现在的问题问题是,当我按下浏览器的后退按钮时,它会尝试转到倒数第二个 URL,即上面步骤 1 中给出的 URL,而不是原始的引用 URL。然后,这会重新触发到步骤 2 的转换。因此,返回引荐 URL 的唯一方法是快速连续点击后退按钮 2 次。

以前有人遇到过这种情况吗?

PS:如果我选择 encodeURI 而不是上面的 encodeURIComponent,它就可以工作。其原因是 encodeURI 最初并未对 : 进行编码。

In my application, I need to redirect using browserHistory created from this package. In order to pass some context, I need to add a query string to the URL. The format in which I receive these params is in JSON. So before being able to call history.push, I first need to stringify and encode the given JSON.

Here's an example:

import { createBrowserHistory } from 'history';

const browserHistory = createBrowserHistory({ window });

const given = { x: 1 };

browserHistory.push(`/foo?test-param=${encodeURIComponent(JSON.stringify(given))}`);

This redirection works...BUT it breaks the native browser back button (sort of). You see what happens is that encodeURIComponent(JSON.stringify(given)) outputs %7B%22x%22%3A1%7D. As soon as the browser sees the %3A part, it automatically changes it into a : in the URL bar. This causes an additional change in the browserHistory, meaning that two URL changes happened:

  1. /foo?test-param=%7B%22x%22%3A1%7D which is the wanted outcome generated by the above code
  2. /foo?test-param=%7B%22x%22:1%7D which is automatically done by the browser (decoding %3A)

The issue now is that when I press the browser's back button, it tries to go to the second last URL which is the one given in step 1 above and not the original referrer URL. This then re-triggers a conversion to step 2. So the only way to get back to the referral URL is to hit the back button 2 times in quick succession.

Has anybody encountered this before?

PS: If I opt for encodeURI instead of encodeURIComponent above, it works. The reason for this is that encodeURI does not encode : to begin with.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

霞映澄塘 2025-01-26 02:53:18

如果这是在电子邮件中进行的,并且URL想要以某种方式嵌入JSON,我会使用十六进制。这应该避免与特殊字符的任何冲突

const given = { x: 1 };

const toHex = s => [...new TextEncoder().encode(s)].map(m => m.toString(16)).join('');

const fromHex = h => 
  (new TextDecoder()).decode(
  new Uint8Array(
  h.match(/.{1,2}/g).map(v => parseInt(v, 16)))); 

const url = `/foo?testparam=${toHex(JSON.stringify(given))}`;

console.log(url);
console.log(JSON.parse(fromHex('7b2278223a317d')));

If this is going in Emails, and the URL want to have JSON embeded somehow, I would use Hex. This should avoid any conflicts with special chars..

eg..

const given = { x: 1 };

const toHex = s => [...new TextEncoder().encode(s)].map(m => m.toString(16)).join('');

const fromHex = h => 
  (new TextDecoder()).decode(
  new Uint8Array(
  h.match(/.{1,2}/g).map(v => parseInt(v, 16)))); 

const url = `/foo?testparam=${toHex(JSON.stringify(given))}`;

console.log(url);
console.log(JSON.parse(fromHex('7b2278223a317d')));

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文