在ColdFusion 9强制下载页面上捕获错误

时间:2012-06-25 23:41:08

标签: exception-handling coldfusion coldfusion-9

我正在为我们的办公室创建一个应用程序,允许办公室中经过身份验证的用户为客户端上传文件,创建下载文件的链接列表,并通过链接列表向客户端发送电子邮件。

当办公室中的用户登录时,会话范围内的UUID被分配。该UUID成为存储上载文件的目录名称。

偶尔我需要清除旧文件并删除目录,但是当发生这种情况时,客户端可能会尝试从旧链接重新下载文件。

在ColdFusion 9中,我如何捕获它并将它们发送到错误页面?我也希望在下载开始后使用类似的代码重定向用户,这样他们就不会在下载过程中只是坐在空白页面上。

这是我的强制下载页面,它采用文件夹名称变量和文件名变量来提供文件。

<cfset folder = #URL.folder#>
<cfset FileDownload = #URL.file#>

<cfset exten = ListLast(FileDownload, ".")>

<cfswitch expression="#exten#">
<cfcase value="zip"><cfset content_type = "application/zip, application/x-zip, application/x-zip-compressed, application/octet-stream, application/x-compress, application/x-compressed, multipart/x-zip"></cfcase>
<cfcase value="ai"><cfset content_type = "application/illustrator"></cfcase>
<cfcase value="eps"><cfset content_type = "application/illustrator, application/octect-stream"></cfcase>
<cfcase value="pdf"><cfset content_type = "application/pdf, application/x-pdf, application/acrobat, applications/vnd.pdf, text/pdf, text/x-pdf"></cfcase>
<cfcase value="psd"><cfset content_type = "image/photoshop, image/x-photoshop, image/psd, application/photoshop"></cfcase>
<cfcase value="jpg"><cfset content_type = "image/jpeg"></cfcase>
<cfcase value="png"><cfset content_type = "image/png"></cfcase>
<cfcase value="tif"><cfset content_type = "image/tiff"></cfcase>
<cfdefaultcase><cfset content_type = "image/jpeg"></cfdefaultcase>
</cfswitch>

<cfset fileToGetSizeOf = expandPath("./#folder#/#FileDownload#") />


<cfoutput><cfheader name="content-disposition" value="attachment;filename=#FileDownload#"><cfheader name="content-length" value="#getFileInfo(fileToGetSizeOf ).size#" />
<cfcontent type="#content_type#" file="#ExpandPath("./#folder#")#/#FileDownload#" deletefile="#delete_file#"></cfoutput>

4 个答案:

答案 0 :(得分:3)

您希望在此处实现三个目标

  1. 安全地提供文件。目前,您无法利用系统(或其他用户)文件,例如像这样(我设置了传递的值而不是URL键):

    <cfset folder = "../../../some/other/path/" />
    <cfset FileDownload = "some_other_file.pdf" />
    
  2. 如果文件或目录不再存在,则显示404页面。

  3. 下载开始后显示一些不错的页面。也许我错过了一些东西,但是在下载开始后重定向用户(=发送标题)非常棘手。

  4. 任何方式,对所有这些都有非常简单和可靠的解决方案

    您应该将文件列表保留在数据库中,因此每条记录可能包括:

    1. 唯一ID。
    2. 文件所有者ID。
    3. 目录名称。
    4. 文件名。
    5. 说明(可选,您可以使用文件名)。
    6. 内容类型(可选,您仍然可以使用带扩展名的方法)。
    7. 创建日期(可选,可用于计划清洁)。
    8. 下载计数器(可选,如果您想限制下载次数)。
    9. 状态(可选,可用于阻止文件系统检查已删除的文件)。
    10. 注意:3-4可以作为单列('path / filename.ext')完成,因为路径是临时的。

      因此,当您的应用程序creates a list of links to download the files and emails the client with the list of links.时,它还会将每个文件记录到数据库中。现在,这些链接中的每一个都可能如下所示:

      <a href="http://yourwebsite.tld/download.cfm?file=#ID#">#DESCRIPTION#</a>
      

      当用户点击链接脚本时,执行以下操作:

      1. 检查数据库中是否存在ID。如果不是 - 重定向到404页面。
      2. 检查当前用户是否与所有者ID匹配。如果不是 - 重定向到404页面。
      3. 检查文件状态,下载计数器(如果需要限制)。如果不是 - 重定向到404页面。
      4. 使用存储的目录和文件名检查实际文件是否存在。如果不是 - 重定向到404页面。
      5. IF 网址中有start个密钥:递增下载计数器,使用cfcontent和内容类型提供文件。
      6. ELSE 呈现页面的HTML,说明“即时开始下载,如果您不想等待,请点击此链接”,其中链接看起来像download.cfm?file=#ID#&start=yes,此外您还有{ {1}}使用相同的网址。
      7. 注意:

        1. 步骤1-4可以包含在具有自定义meta http-equiv="refresh"的单个try / catch块中,因此您可以拥有一个重定向位置。
        2. 这里的步骤5的诀窍是用户在点击下载链接时会留在页面上,并且不会看到空白页面。对于目标#3,这不是完全解决方案,但如果没有一些技巧,很难做出更好的事情。也许我错了,有人可以在这里提出更好的方法,这很酷。您可以删除“单击此链接部分”以使此页面看起来“自然”。

答案 1 :(得分:0)

如果您的网站有404页面,则表示您已将其指向错误页面。或者至少你的网络服务器是。如果您没有设置站点范围的404页面,请将其设置为cfm页面以提供一些额外的功能(日志记录,警报等)

答案 2 :(得分:0)

您可以使用FileExists检查是否存在并根据该决定做出决定:

<cfif NOT FileExists(fileToGetSizeOf)>
  <!--- send a 404 --->
<cfelse>
  <!--- send the file --->
</cfif>

答案 3 :(得分:0)

您可以使用 FileExists(absolute_path)功能检查下载文件是否存在。