为啥 JavaScript 拦截“在野外”(在网页上)工作的 formData 不能在小提琴中工作?
Posted
技术标签:
【中文标题】为啥 JavaScript 拦截“在野外”(在网页上)工作的 formData 不能在小提琴中工作?【英文标题】:Why does JavaScript to intercept formData that works 'in the wild' (on a web page) not work in a fiddle?为什么 JavaScript 拦截“在野外”(在网页上)工作的 formData 不能在小提琴中工作? 【发布时间】:2019-11-05 09:18:47 【问题描述】:我在提交事件上使用回调函数来检索 formData。它在我的web site 上的这个test page 上正常工作。我试图建立一个小提琴来解决另一个问题。我发现相同的代码在小提琴中不起作用。它返回一个带有array.length == 0
的formData,而不是正确的formData。
代码使用 jQuery 作为 document.ready 函数。 jQuery 已正确加载。
JavaScript:
01: /* doc.ready w/ traditional callback fn for event listener */
02:
03: $(document).ready( function()
04: init();
05:
06: ); // end doc.ready
07:
08: function init()
09: document.addEventListener("submit", processFormData);
10: // end def fn init
11:
12: functon processFormData(event)
13: var formData = new FormData();
14: event.preventDefault();
15: formData = $( 'form' ).serializeArray();
16:
17: console.log('formData : ', formData);
18:
19. // end def fn processFormDat;
在实时表单中输入数据后,formData 返回一个数组,在相关部分,是这样的:
3: Object name: "select-yui_3_nnn ... nnn-field", value: "unsure"
4: Object name: "select-yui_3_nnn ... nnn-field", value: "A"
5: Object name: "select-yui_3_nnn ... nnn-field", value: "B"
6: Object name: "select-yui_3_nnn ... nnn-field", value: "A"
7: Object name: "select-yui_3_nnn ... nnn-field", value: "unsure"
8: Object name: "select-yui_3_nnn ... nnn-field", value: "C"
length: 9
(formData.name
'yui' 属性不是常量。它们在每次页面加载时动态生成。它们不能用于引用项目。)
在the fiddle,控制台是这样的:
formData : Array []
formData.length == 0
.
那么,问题是为什么?
HTML: 我的网站是在 Squarespace 平台上使用它的“表单块”之一构建的。 html 非常复杂。我不会尝试在这里复制它。
小提琴中的 HTML 很简单。我在这里复制它,这样你就不必点击了。
01; <form method="POST">
02: <div>
03: <label>First Name
04: <input type="text" size="25">
05: </label>
06: </div>
07: <div>
08: <label>Last Name
09: <input type="text" size="25">
10: </label>
11: </div>
12: </form>
console.config(
maxEntries: Infinity
);
/* doc.ready w/ traditional callback fn for event listener */
$(document).ready(function()
init();
); // end doc.ready
function init()
document.addEventListener("submit", processFormData);
// end def fn init
function processFormData(event)
var formData = new FormData();
event.preventDefault();
formData = $('form').serializeArray();
console.log('formData : ', formData);
// end def fn processFormData
.as-console-wrapper
max-height: 100% !important;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form name="testForm" method="post">
<div>
<label>First Name
<input type="text" name="fname" size="25">
</label>
</div>
<div>
<label>Last Name
<input type="text" name="lname" size="25">
</label>
</div>
<div>
<label>email address
<input type="email" name="email" size="25">
</label>
</div>
<div>
<label>08:30 Keynote Speaker
<select name="select0830">
<option value="">unsure</option>
<option value="attend">attend</option>
<option value="not attend">not attend</option>
</select>
</label>
<label>09:00 Classes
<select name="select0900">
<option value="">unsure</option>
<option value="class room A">room A</option>
<option value="class room B">room B</option>
</select>
</label>
<label>10:30 Classes
<select name="select1030">
<option value="">unsure</option>
<option value="class room A">room A</option>
<option value="class room B">room B</option>
</select>
</label>
</div>
<div>
<input type="submit" value="submit form">
</div>
</form>
【问题讨论】:
参见api.jquery.com/serializeArray:“.serializeArray() 方法使用标准 W3C 规则来成功控制以确定它应该包含哪些元素;特别是该元素不能被禁用并且 必须包含名称属性。” 另外,您需要在问题中包含minimal reproducible example。见How to Ask。最好的方法是使用内置的 sn-p 编辑器。您当前的问题包含不完整的代码和不必要的行号,并且缺少一些元素。 @Herohtar :感谢您指出堆栈片段。我在问题中添加了一个。感谢您提供有关name
属性的信息。在 sn-p 中,我在表单字段中添加了名称。这解决了问题。它也解释了为什么 js 在我的测试页面上工作。我使用浏览器的元素检查器查看每个字段的名称属性/我应该考虑尝试在 serializeArray()
上查找文档。至于不完整的代码,我相信你错了。 19行js都在测试页面的js里面。我看不到任何缺失的元素。再次感谢,非常感谢!
我没有弄错不完整的代码,但我说的是 HTML,而不是 javascript——看看你的问题中仍然存在的原始 HTML 列表:有一个<div>
末尾的标签没有结束标签,它不包含任何提交按钮,<form>
也缺少它的结束标签。
@Herohtar 感谢您的坚持。我为草率的 HTML 道歉。再次感谢您之前的两个 cmets,当我与 Nick Parsons 下面的回答一起阅读它们时,给了我答案。我将他标记为已接受的答案,但也对您的两个 cmets 投了赞成票。
【参考方案1】:
您的问题在于您对方法的使用:
$('form').serializeArray();
.serializeArray()
将查看您给它的表单,并使用表单中每个表单控件的name
字段构建一个对象数组。正如您所说,name
字段是动态生成的,只有在生成它们时您才会得到结果。如果永远不会生成 name
属性,那么您将永远不会获得数据(因为它们永远不会在您的 sn-p 中生成,您将永远不会获得数据)。
因此,为了让.serializeArray
工作,您需要为表单输入提供name
属性。
查看工作示例here
另外请注意,不需要new FormData()
。你正在用$('form').serializeArray();
返回的数组覆盖这个数据
【讨论】:
非常感谢!在您的回答和@herchtar 的 cmets 之间,我理解。它解释了为什么代码在我网站的测试页面上有效。每个表单元素都有一个名称属性。它们的选择器名称确实是“yui”名称。但是 doc.ready 项目应该处理这个问题,不是吗?在显示表单时,这些标签都具有名称属性。 doc.ready 阻止 js 执行,直到所有 HTML 元素都到位。我不能 使用 js 中的 name 属性,但至少在我的情况下,我不需要。再次感谢您的解释。这是最有帮助的。 @alxfyv 是的,你是对的。名称属性应该动态添加到您的元素中,因此无需为您的站点添加名称属性。以上是关于为啥 JavaScript 拦截“在野外”(在网页上)工作的 formData 不能在小提琴中工作?的主要内容,如果未能解决你的问题,请参考以下文章