【问题标题】:How do I store JavaScript variables in a website URL?如何在网站 URL 中存储 JavaScript 变量?
【发布时间】:2020-07-29 16:09:18
【问题描述】:

我有一个游戏,https://e4494s.neocities.org/bounce.html,玩家可以在其中玩弄各种变量并修改模拟的物理特性。我想添加一个按钮,将用户带到一个没有文本框或任何内容的单独页面,并且他们修改的值存储在 URL 中,以便他们可以将其发送给某人或为自己保存。例如,如果他们将 bounciness 修改为 0.5,将 gravity 修改为 -0.25,则单击“获取链接”按钮会将他们发送到 https://e4494s.neocities.org/fullscreenbounce.html/bounciness=0.5;gravity=-0.25。 (我可以用任何其他方式将它们存储在那里,例如 /0.5/0.25 或任何其他方法)。问题是,当我转到此链接时,它试图转到我的网站上不存在的页面“bounciness=0.5;gravity=-0.25”。但我知道有一些方法可以在 URL 中存储变量,例如 Doob 先生的游戏 Voxels。当我制作更多体素时,URL 会发生变化,我可以简单地复制该 URL,它会包含我每次访问它时构建的确切内容。

那么我该如何将它融入我的游戏中呢?

【问题讨论】:

  • 欢迎来到 Stack Overflow。请编辑您的问题以包含您迄今为止尝试过的详细信息以及您在minimal, reproducible example 中使用的代码,以便我们了解正在发生的事情并能够提供帮助。

标签: javascript html url


【解决方案1】:

我建议您阅读此相关问题:Adding a parameter to the URL with JavaScript

尽管您可能想考虑使用本地存储(除非您希望将这些用作共享链接)。本地存储将允许将值保存在用户的浏览器中,并且如果他们重新加载没有查询参数的页面,它们仍然存在。看看这个:https://www.w3schools.com/html/html5_webstorage.asp

【讨论】:

  • 嗨,汤姆,我认为您提供给另一个问题的链接很好,但 OP 明确表示“他们修改的值存储在 URL 中 ,因此他们可以将其发送到某人或为自己保存” - 所以它是用于您提到的共享链接。
【解决方案2】:

存储可访问的、冗余的 javascript 数据的一种方法是使用 json。因此,您的游戏的完整参数化可以由以下 字符串 表示:

{ "bounciness": 0.5, "gravity": -0.25, "friction": 1.2, "windVector": { "ang": 2.7314, "mag": 4.23 } }

如果该字符串存储在名为 dataString 的变量中,您可以执行以下操作:

let { bounciness, gravity, friction, windVector } = JSON.parse(dataString);

现在的诀窍是将dataString 中的值放入URL。 Json 适用于任意值,但它不能正确嵌入到 url。我们需要进行额外的步骤,将 json 编码为 确实 适合 url 的形式。一种这样的编码是 base64,base64 编码已经通过全局 btoa 函数 (mdn) 存在,所以这个过程看起来像:

original raw data -> json data -> base64 encoded json data

如果原始数据保存在名为 params 的变量中,则要插入 url 的值将是:

let params = { bounciness: 0.5, gravity: -0.25, friction: 1.2, windVector: { ang: 2.7314, mag: 4.23 } }
let valueForUrl = btoa(JSON.stringify(params));
console.log(valueForUrl);

这是一个示例,当原始数据更新时,url 值会自动更新:

let rawData = { "bounciness": 0.5, "gravity": -0.25, "friction": 1.2, "windVector": { "ang": 2.7314, "mag": 4.23 } }

let resultJson = document.querySelector('.result.json');
let resultBase64 = document.querySelector('.result.base64');

let elems = [ 'bounciness', 'gravity', 'friction', 'windVector-ang', 'windVector-mag' ]
  .map(v => document.querySelector(`[name="${v}"]`));

let [ bElem, gElem, fElem, waElem, wmElem ] = elems;

let fullUpdate = () => {
  if (document.querySelector(':invalid')) {
    resultJson.innerHTML = 'Invalid input';
    resultBase64.innerHTML = 'Invalid input';
    return;
  }
  
  let json = JSON.stringify(rawData);
  resultJson.innerHTML = json;
  resultBase64.innerHTML = btoa(json);
  
};
let updateElem = (elem, obj, prop) => {
  elem.value = obj[prop].toString();
  elem.addEventListener('input', evt => {
    if (elem.matches(':valid')) obj[prop] = parseFloat(elem.value, 10);
    fullUpdate();
  });
};

updateElem(bElem, rawData, 'bounciness');
updateElem(gElem, rawData, 'gravity');
updateElem(fElem, rawData, 'friction');
updateElem(waElem, rawData.windVector, 'ang');
updateElem(wmElem, rawData.windVector, 'mag');
fullUpdate();
input { display: block; }
input:valid { background-color: rgba(0, 150, 0, 0.2); }
input:invalid { background-color: rgba(150, 0, 0, 0.2); }

p { margin: 0; margin-top: 5px; }

.result {
  font-family: monospace;
  border: 2px solid #a0a0a0;
  margin-top: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
<p>Bounciness</p>
<input type="text" pattern="[-+]?[0-9]+([.][0-9]+)?" name="bounciness" />
<p>Gravity</p>
<input type="text" pattern="[-+]?[0-9]+([.][0-9]+)?" name="gravity" />
<p>Friction</p>
<input type="text" pattern="[-+]?[0-9]+([.][0-9]+)?" name="friction" />
<p>Wind Angle</p>
<input type="text" pattern="[-+]?[0-9]+([.][0-9]+)?" name="windVector-ang" />
<p>Wind Magnitude</p>
<input type="text" pattern="[-+]?[0-9]+([.][0-9]+)?" name="windVector-mag" />

<p>JSON</p>
<p class="result json"></p>
<p>Base64</p>
<p class="result base64"></p>

现在,当使用提供的 url 加载新页面时,您可以从 base64(使用 atob)转换回 json,然后从 json 转换回原始数据。假设url中的值在变量urlData中:

let urlData = 'eyJib3VuY2luZXNzIjowLjUsImdyYXZpdHkiOi0wLjI1LCJmcmljdGlvbiI6MS4yLCJ3aW5kVmVjdG9yIjp7ImFuZyI6Mi43MzE0LCJtYWciOjQuMjN9fQ';
console.log(JSON.parse(atob(urlData)));

请注意,base64 并不是唯一可能的编码(而且它可能比其他编码效率更低!)

【讨论】:

    猜你喜欢
    • 2015-03-19
    • 2021-07-16
    • 2020-12-22
    • 1970-01-01
    • 1970-01-01
    • 2019-12-31
    • 1970-01-01
    • 2021-06-22
    • 1970-01-01
    相关资源
    最近更新 更多