【问题标题】:Is it bad to store temporary data into hidden element? [closed]将临时数据存储到隐藏元素中是不是很糟糕? [关闭]
【发布时间】:2013-04-07 05:22:54
【问题描述】:

在一次面试中,一旦我参加了,我被要求创建一个基于 java 脚本的功能,据说我在其中创建一个表单(比如名字、姓氏、电子邮件、年龄)和一个列表(实际上列表是一种存储多个条目的另一种表单)在此表单下方。提交此表单后,列表中添加了一个新行。但是,可以删除任何先前添加的列表行。并且添加删除后,最后需要存储这个最终的listing状态。 (表单发布和服务器端脚本的种类进入图片)

所以我做了什么,在提交表单时,在列表表中添加一个新的<tr> 行,同时我使用 jQuery 序列化序列化除提交按钮之外的所有表单数据,并将其存储在列表表单的一个隐藏元素中。

在删除列表行时,我删除了 <tr> 行以及同一行的相应隐藏元素。

一切正常,没有任何错误。但是面试官问我“我使用的方法(隐藏元素)真的合适吗?”。

我回答说,我可以使用 json 吗? 但无法破解采访。 所以我想知道在这种情况下我们可以用来存储数据的最佳方法是什么?

【问题讨论】:

  • 不能存储在数组中吗?我的意思是您将值存储在数组中,而不是隐藏元素。
  • 面试官可能只是想看看他/她批评你时的反应。
  • 我在 30 分钟内完成了所有这些工作,即使受到他的批评,我也对自己所做的事情充满信心。实际上我申请的是一家知名的 IT 公司。
  • 有时候我真的不明白。这太本地化了,没有建设性。这是一个code review 充其量,当然不值得 19 分。
  • @Ohgodwhy,你是真的。但是当这一切发生在我身上时,我的信心就下降了。所以想知道最好的方法。而且我没有错,SO 也是您可以获得最佳方法的地方。

标签: javascript jquery html dom


【解决方案1】:

如果用户可以信任它,那么在客户端存储数据没有任何问题,并且当他弄乱它时,您的系统也不会发生任何可怕的事情。

我可以看到使用隐藏字段(或 cookie)的唯一问题是它们会随每个请求一起发送,这可能会浪费带宽。不确定这是否适用于您的情况,可能不适用,因为您说您只在完成所有操作后提交一次。

【讨论】:

  • 那么我应该考虑到,面试官希望我准确地实现他的想法,而我没有这样做,他拒绝了。
  • 也许吧。这是一个常见的问题。或者也许他只是想让你捍卫/解释你的方法(你应该能够做到)。
  • 我没有收到关于在页面刷新时维护数据的通知。是否可以仅通过 javascript 在页面刷新时维护此类数据?
  • localStorage 是需要了解的。
  • 如果我没记错那么它只是在 HTML5 中引入的。对吧,先生?
【解决方案2】:

感谢 HTML5,我们现在能够在所有 HTML 元素上嵌入自定义数据属性。这些新的自定义数据属性由两部分组成:

  • 属性名称 数据属性名称必须至少有一个字符长,并且必须以“data-”为前缀。它不应包含任何大写字母。
  • 属性值 属性值可以是任意字符串。

使用这种语法,我们可以将应用程序数据添加到我们的标记中,如下所示:

<ul id="vegetable-seeds">
  <li data-spacing="10cm" data-sowing-time="March to June">Carrots</li>
  <li data-spacing="30cm" data-sowing-time="February to March">Celery</li>
  <li data-spacing="3cm" data-sowing-time="March to September">Radishes</li>
</ul> 

我们现在可以在我们网站的 JavaScript 中使用这些存储的数据来创建更丰富、更具吸引力的用户体验。想象一下,当用户点击一种蔬菜时,浏览器中会打开一个新图层,显示额外的种子间距和播种说明。由于我们添加到 &lt;li&gt; 元素中的 data- 属性,我们现在可以立即显示这些信息,而无需担心进行任何 Ajax 调用,也无需进行任何服务器端数据库查询。

来源:HTML5 Doctor

我相信还有其他方法。

【讨论】:

  • 还没有使用过 html5,所以只是动摇我的知识,这个标签适用于所有浏览器吗?
  • 重要的是要注意元素的属性不会影响浏览器呈现元素的方式。 IE 甚至使用了非标准的 HTML 4 属性。无论使用哪种浏览器,利用 data 属性都不应成为问题。
  • 好的,谢谢@Ohgodwhy。现在开始尝试。
  • @Ohgodwhy 但是,访问这些属性的方式存在明显差异。 .dataset.xxx 与 .getAttribute('data-xxx').
【解决方案3】:

“行之有效”的解决方案的问题在于它们不够抽象,因此往往会在未来引发问题。考虑你的例子;如果您决定将临时数据存储在本地存储中(以允许用户关闭浏览器并稍后返回),则必须重写存储数据的方式。如果将其存储在变量中,则可以像添加“提交到服务器”或“传递到任何其他函数”功能一样轻松地添加“保存到本地存储”。除了发布到服务之外,您的“隐藏元素”方法必须重写。

【讨论】:

  • 如果出现新需求,稍后再重写并不总是一个问题。保持简单是有好处的。无需为手头的任务做多余的事情,尤其是在这会带来复杂性的情况下。
  • 你好,Brian,我更喜欢@Thilo,因为我可以考虑你提到的几点,但考虑到面试和时间有限,我这样做了。
  • 是的,你这样做了......但失败了:/
【解决方案4】:

实际上,您可以使用 jQuery 将数据添加到 html 元素中,而不是使用隐藏元素。这是一种更好的方法,可以使您的数据对用户不那么明显/直接。检查 jQuery 中的 data()。

【讨论】:

  • 防篡改?怎么样?
  • 什么是耐火?我不知道。请解释
  • 您可以将值存储到自定义命名变量。所以乍一看,您不会直接获得正在使用的变量,而隐藏元素并非如此,这使得它更加明显。
  • 没有任何客户端是防篡改的。
  • @BhumiSinghal,我会说不。
【解决方案5】:

客户端的另一种方法是单独保留对象列表,并且仅将对每个项目的引用存储在 DOM 元素的属性中。这种方法与 jQuery 的$.fn.data() 提供的方法非常相似,并且具有以下优点:

  1. 您不必序列化任何内容,数据保持其原始格式;应该说,你也可以通过添加一个属性来实现这一点。

  2. 您的所有数据都保存在一个地方,而不是分散在 DOM 中。

这是一个示例实现:

(function(ns) {

var entries = {},
entryId = 1;

ns.Entries = {
   addEntry: function(data) {
     entries[entryId] = data;
     return entryId++;
   },
   getEntryById: function(id) {
     return entries[id] || null;
   }
};

}(this));

调用 Entries.addEntry 会返回一个标识符,您可以将其存储在 DOM 元素的属性之一中:

tr.entryId = Entries.addEntry(data);

稍后你可以使用那个entryId属性在条目列表中找到对应的数据并使用它。

var data = Entries.getEntryById(tr.entryId);

Demo

当然,这个特定的功能也可以通过使用会话在服务器端解决。

【讨论】:

  • 杰克。我慢慢明白你想说什么,但为了更多的理解,希望看到它起作用。请检查演示链接,它不适合我。
  • @RajanRawal 页面是空的,你应该看看控制台或者切换到编辑模式; jsbin.com/arucuj/1/edit
  • 它被称为wrapper,你做了什么?
  • @RajanRawal 你是在说我写代码的方式吗?我使用闭包来封装实际存储,因此您只能通过我在Entries 下公开的函数来引用数据。
  • 我彻底明白了你提到的这两点。我从未使用过如此复杂的方式。你能在演示链接中多做一些编码吗?请...
【解决方案6】:

首先,一个页面上的多个表单是错误的 - 这是数据丢失反模式。正确的方法是把所有东西都放在一种形式中。这样,即使没有 JS,它也可以工作,您可以使用 JS 来提高可用性,而不是提供基本功能。该解决方案将优雅地降级,并且易于调试和维护。

当然,将数据保存在隐藏字段中是一种有效的技术。

【讨论】:

  • 同意数据丢失反模式。
【解决方案7】:

通过将提交的数据写入表单本身并再次从中读取,您将这两个元素绑定在一起 - 据说它们是紧密耦合的。

如果另一个要求也出现在表格中显示以前提交的数据,会发生什么情况?还是将表单放在单独的页面上?

如果您采用更多的 MVC 方法,您可以分离出各个部分的逻辑 - 读取、写入和发送数据。例如,正如您所说,从 JSON 模型中写入和读取。这将使每个方面在未来更容易扩展。

【讨论】:

  • 有人可能会争辩说,在表单完成之前将所有状态保留在客户端中,这有助于在 MVC 中很好地分离“视图”组件。
  • 其实我用的是twp分离形式。一个用于主条目,另一个用于显示列表并添加了那些隐藏元素
  • @Thilo,绝对同意在 JS 应用程序的客户端建模数据没有任何问题。也许这是我阅读原始问题的方式,但听起来数据建模的方式是基于原始提交的表单,而不是对数据结构最有意义的方式。如果没有更多关于采访的细节,很难肯定地发表评论
【解决方案8】:

我不会直接回答你的问题,但会重点介绍你选择的面试和方法。

我会说您选择了错误的方式,并且您应用此解决方案的知名 IT 公司可能会遇到问题。

您选择了将所有内容存储在客户端的方式,但您不应该这样做!由于您的客户可能会以这种方式丢失大量数据,因为想象一下您的列表表单永远不会发送的情况?用户只会忘记点击发送(永远不要相信用户!)。然后你就失去了一切……你工作的全部进展……假设你已经添加了 50 个列表项……

另外添加这样的项目很容易使您的会话过期(对服务器没有请求)并且不会保存任何数据,因为用户必须重新登录。你也必须处理它,否则你将失去一切!

很抱歉有感叹号,但我认为数据至关重要(尤其是对您的客户而言),因此永远不要提供可能让客户以某种方式丢失数据的解决方案。

所以:

将数据存储在 HTML 元素中还不错,但您需要非常小心地应用此解决方案。

【讨论】:

  • Carlos,我真的从您的回答中学到了新东西,但仅使用 javascript 而不是使用任何服务器端脚本是强制性的。如果允许,那么我可以发送 ajax,将其存储在数据库中,然后仅列出。希望那是正确的。
  • 好的 - 从你的问题我看不出有任何要求,你不能在这个过程中进行 ajax 调用。但如果这是真的,那么我不会为他们工作,因为在这种情况下他们似乎是无知的。任何仅存储在客户端的数据都可以被篡改(在其他答案中)。因此,您将其存储在那里的方式并不重要,只要您可以将其取回即可。那么你的回答很好,因为它运作良好。
猜你喜欢
  • 2020-01-29
  • 1970-01-01
  • 2012-02-25
  • 1970-01-01
  • 2013-10-16
  • 2013-05-08
  • 2013-04-17
  • 2022-07-21
  • 1970-01-01
相关资源
最近更新 更多