使用cfhttp上传文件会附加换行符(即使是二进制文件)

时间:2010-09-17 20:00:28

标签: forms coldfusion file-upload

更新:我找到了解决方法。如果我提交一个虚拟表单字段和文件,它可以工作。这是一个ColdFusion错误,还是HTTP规范中有些内容表明表单必须包含至少一个非文件表单字段?

更新2 :我确信这是一个ColdFusion cfhttp错误。这是基于Leigh的答案以及我使用下面的代码使用javascript提交仅使用 文件元素的表单的事实,并且它工作正常:

<form enctype="multipart/form-data" action="<cfoutput>#CGI.PATH_INFO#</cfoutput>" method="POST" name="theForm">
  <input name="theFile" type="file" /><br/>
</form>
<a href="#" onclick="document.theForm.submit()">submit</a>

我在将文件从ColdFusion服务器上传到另一个网络服务器时遇到了问题。似乎cfhttpparam type="file"不加选择地在文件末尾添加换行符(回车符和换行符)。这打破了二进制文件。当我通过表单字段手动上传文件时,不会发生。我尝试过有和没有mimetype参数,我试过用各种二进制格式(exe,zip,jpg)说谎mimetype,但没有任何效果。是否有一些我缺少的参数,或者这是ColdFusion中的一个错误? (我在WinXP上运行CF 8.0.1.195765。)

下面是我正在使用的测试代码,它只是将文件上传到同一目录。手动上载有效,但基于服务器的上载最终会将CRLF附加到文件中。

<cfset MyDir = "C:\test" />
<cfset MyFile = "test.zip" />

<cfif IsDefined("Form.TheFile")>
  <cffile action="upload" fileField="theFile" destination="#MyDir#" nameConflict="MakeUnique" />
<cfelse>
  <cfhttp url="http://#CGI.SERVER_NAME##CGI.SCRIPT_NAME#" method="POST" throwOnError="Yes">
    <cfhttpparam type="file" name="theFile" file="#MyDir#\#MyFile#" />
  </cfhttp>
</cfif>

<html><body>
<h2>Manual upload</h2>
<form enctype="multipart/form-data" action="<cfoutput>#CGI.PATH_INFO#</cfoutput>" method="POST">
  <input name="theFile" type="file" /><br/>
  <input type="submit" value="Submit" />
</form>
</body></html>

3 个答案:

答案 0 :(得分:4)

  

或HTTP规范中是否存在某些内容   表示表格必须至少包含   一个非文件格式字段?

我不确定。但根据these definitions,似乎只包含文件输入的POST应该是有效的。所以我怀疑问题可能是ACF中的CFHTTP。

根据Fiddler,来自ACF中cfhttp调用的原始内容在结束边界之前包含一个额外的新行(在十六进制视图中为0D 0A)。但在Railo之下却没有。所以我认为ACF的cfhttp可能是罪魁祸首。

示例代码:

<cfhttp url="http://127.0.0.1:8888/cfusion/receive.cfm" method="post">
    <cfhttpparam name="myFile" type="file" file="c:/test/testFile.zip" mimetype="application/octet-stream" />
</cfhttp>

结果Railo 3.1.2

POST /railo/receive.cfm HTTP/1.1
User-Agent: Railo (CFML Engine)
Host: 127.0.0.1:8888
Content-Length: 382
Content-Type: multipart/form-data; boundary=m_l7PD5xIydR_hQpo8fDxL0Hb7vu_F8DSzwn

--m_l7PD5xIydR_hQpo8fDxL0Hb7vu_F8DSzwn
Content-Disposition: form-data; name="myFile"; filename="testFile.zip"
Content-Type: application/octet-stream; charset=ISO-8859-1
Content-Transfer-Encoding: binary

PK
&�1=�cN'testFile.txtTestingPK
&�1=�cN' testFile.txtPK:1
--m_l7PD5xIydR_hQpo8fDxL0Hb7vu_F8DSzwn--

结果ACF(版本8和9)

POST /cfusion/receive.cfm HTTP/1.1
Host: 127.0.0.1:8888
... other headers removed for brevity ....
Content-type: multipart/form-data; boundary=-----------------------------7d0d117230764
Content-length: 350

-------------------------------7d0d117230764
Content-Disposition: form-data; name="JobFile"; filename="c:\test\testFile.zip"
Content-Type: application/octet-stream

PK
&�1=�cN'testFile.txtTestingPK
&�1=�cN' testFile.txtPK:1

-------------------------------7d0d117230764--

答案 1 :(得分:1)

也许Railo 3.1.2和ColdFusion 9处理的方式有点不同,但你的代码对我来说有点不对劲。

您的CGI.PATH_INFO不适用于此。

虽然浏览器非常智能,可以使用没有主机名的路径,但使用完整主机名+脚本路径+脚本名称时,CFHTTP感觉更好。注意:cgi.SCRIPT_NAME在CF9中工作,Railo需要cgi.SERVER_NAME作为前缀,尽管我觉得这一般更正确。

这就是为什么代码的一些修改版本对我来说很好。 Zip文件上传和发布时不会损坏。

形式:

<form enctype="multipart/form-data" action="<cfoutput>#cgi.SCRIPT_NAME#</cfoutput>" method="POST">
  <input name="theFile" type="file" /><br/>
  <input type="submit" value="Submit" />
</form>

CFHTTP:

  <cfhttp url="#cgi.SERVER_NAME##cgi.SCRIPT_NAME#" method="POST" throwOnError="Yes">
    <cfhttpparam type="file" name="theFile" file="#MyDir#/#MyFile#" />
  </cfhttp>

希望这有帮助。

答案 2 :(得分:1)

我获得了额外的换行符和文件附加回车权。对我来说问题是/是cfhttp和cfloop的组合。一旦我将文件创建分成3个部分:Create,cfloop endrow-1,然后附加最后一条记录。

看起来像是一种愚蠢的方式,但没有额外的换行。