更新:我找到了解决方法。如果我提交一个虚拟表单字段和文件,它可以工作。这是一个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>
答案 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,然后附加最后一条记录。
看起来像是一种愚蠢的方式,但没有额外的换行。