代码之家  ›  专栏  ›  技术社区  ›  Kip

使用cfhttp上载文件会附加新行(即使是二进制文件)。

  •  6
  • Kip  · 技术社区  · 14 年前

    更新 :我找到了一个解决办法。如果我随同文件一起提交一个虚拟表单字段,它就会工作。这是一个ColdFusion bug,还是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服务器上载到另一个Web服务器时遇到问题。看来 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 回复  |  直到 14 年前
        1
  •  4
  •   Leigh josh poley    14 年前

    或者HTTP规范中有什么内容 也就是说表单必须至少包含 一个非文件表单域?

    我不确定。但是根据 these definitions 似乎只包含文件输入的日志应该是有效的。所以我怀疑问题可能是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--
    
        2
  •  1
  •   Sergey Galashyn    14 年前

    也许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>
    

    希望这有帮助。

        3
  •  1
  •   Chris    13 年前

    我还得到了额外的换行和文件附加的回车。对我来说,问题是cfhttp和cfloop的结合。一旦我将文件创建分为三个部分:创建,cfloop endrow-1,然后附加最后一条记录。

    似乎是一个笨拙的方法,但没有额外的线饲料。