为什么 FORM 范围显示的值少于此 AJAX 文件上传者实际提交的值?

Why is the FORM scope showing fewer values than were actually submitted by this AJAX file uploader?

我不确定我是否理解如何表达我的问题,但我相信它特定于 ColdFusion 对某些 AJAX 表单数据的处理,尽管我提到了特定的 JavaScript 插件。

我正在尝试在 ColdFusion 2011 服务器上实现 FilePond uploader,我已经在前端对其进行了很好的配置(它可以将文件上传到 tmp 文件夹),但我的问题是不知道如何让 ColdFusion 处理它在每次上传时一起发送的额外元数据。在我看来,这些数据的格式与普通的旧隐藏输入字段的格式不同。

当我使用 Dev Tools 检查网络请求时,它看起来与我处理过的其他表单不同。有两个 "filepond" 条目,一个是 JSON 对象,另一个是二进制图像。当我 时,我只得到 tmp 上传的文件路径,我可以处理它。但是如何访问包含 "parentid" 的屏幕截图中的 JSON?我试过的任何东西,例如 form.FilePond[1],似乎都有效并抛出错误。

更新 CF 表单处理页面的输出:

第一行是 Form.FilePond.

的输出

第二个是Form的cfdump。

第三个是 cfdump URL.

第 4 个是 getHttpRequestData() 的 cfdump

更新:

针对 CF2016 提交的错误(对 CF11 的核心支持在 2019 年 4 月之后结束)

  • CF-4204103 - FORM 当相同命名字段包含 type=file
  • 时,范围缺少值
  • CF-4204102 - sameFormFieldAsArray 设置不适用于 enctype="multipart/form-data"

经过一些测试,我断定这是一个 ColdFusion 错误。

问题:

问题似乎是在这些情况下发生的

  • 请求是 multipart/form-data POST
  • 包含多个具有相同名称
  • 的字段
  • 这些字段中至少有 1 个是文件字段,即 type="file"
  • 提交的第一个字段(组内)是不是文件字段

在这些条件下,ColdFusion 似乎忽略了 第一个文件字段 之前的所有内容。 (如果您检查 filepond source ut 确认元数据字段在 之前 提交任何文件字段)。这就是为什么在转储 FORM 范围时元数据值不出现的原因。

请注意,this.sameFormFieldsAsArray 设置无效,因为它不适用于 multipart/form-data 请求。

测试用例

下面是一个测试用例。请注意,当相同的命名字段出现在第一个文件字段 之后 时,结果就是您所期望的结果?

<cfdump var="#form#" label="Form scope">

<form method="post" enctype="multipart/form-data">
    <br>First:
    <input type="file" name="fileFirst"><br>
    <input type="text" name="fileFirst" value="Lions"><br>

    <br>Last:
    <input type="text" name="fileLast" value="Tigers"><br>
    <input type="file" name="fileLast"><br>

    <br>Middle:
    <input type="text" name="fileMiddle" value="Bears"><br>
    <input type="file" name="fileMiddle"><br>
    <input type="text" name="fileMiddle" value="Oh My"><br>

    <input type="submit">
</form>

解决方法

This blog 提供了一种使用 FORM 范围的未记录功能的解决方法。使用 form.getPartsArray() 提供对两个 "filePond" 字段的访问,允许您提取已删除字段的值。不理想,但在问题解决之前确实有效。

请记住,这是一个未记录的功能,因此请务必隔离代码以便更轻松地进行更改,以防 Adob​​e 将来更改或删除该功能(他们之前已经做过,所以公平警告!)。

<cfscript>
    // dump raw form fields 
    for (part in form.getPartsArray()) {
        writeDump({ fieldName = part.getName()
                    , isFile  = part.isFile()
                    , fieldValue = (part.isFile() ? part.getFileName() : part.getStringValue())
                }
        );
    }
</cfscript>