1

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

当办公室中的用户登录时,他们会在其会话范围内分配一个 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

4 回答 4

3

您想在这里实现三个目标:

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

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

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

无论如何,所有这些都有非常简单可靠的解决方案

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

  1. 唯一身份。
  2. 文件所有者 ID。
  3. 目录名称。
  4. 文件名。
  5. 描述(可选,可以使用文件名)。
  6. 内容类型(可选,您仍然可以使用带有扩展名的方法)。
  7. 创建日期(可选,可用于定期清洁)。
  8. 下载计数器(可选,如果您想限制下载次数)。
  9. 状态(可选,可用于防止文件系统检查已删除文件)。

注意: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. 如果URL 中有start键:增加下载计数器,使用 cfcontent 和内容类型提供文件。
  6. ELSE呈现页面的 HTML,上面写着“下载将立即开始,如果您不想等待,请单击此链接”,其中链接看起来像download.cfm?file=#ID#&start=yes,而且您拥有meta http-equiv="refresh"相同的 URL。

笔记:

  1. 步骤 1-4 可以用 custom 包裹在单个 try/catch 块中errorCode,因此您可以有一个重定向位置。
  2. 此处第 5 步的技巧是用户在单击下载链接时将停留在页面上,并且不会看到空白页面。这不是目标 3的精确解决方案,但如果没有一些技巧,很难让事情变得更好。也许我错了,有人可以在这里提出更好的方法,这会很酷。您可以删除“单击此链接部分”以使此页面看起来“自然”。
于 2012-06-26T06:29:08.627 回答
0

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

于 2012-06-26T00:28:43.967 回答
0

您可以使用它FileExists来检查是否存在并基于此做出决定:

<cfif NOT FileExists(fileToGetSizeOf)>
  <!--- send a 404 --->
<cfelse>
  <!--- send the file --->
</cfif>
于 2012-06-26T03:46:24.040 回答
0

您可以使用FileExists(absolute_path)函数来检查下载的文件是否存在。

于 2012-06-27T07:34:13.357 回答