打开“另存为”对话框以下载图像

Posted

技术标签:

【中文标题】打开“另存为”对话框以下载图像【英文标题】:Open "Save As" Dialog Box To Download Image 【发布时间】:2014-03-24 14:18:49 【问题描述】:

我一直在到处寻找这个问题的答案,但没有运气。

我想要一个可以打开“另存为”对话框的按钮或链接。简单吗?

我知道我可以在新窗口/选项卡中打开图像(就像我现在所做的那样),然后使用 right-click, save as 方法,但因为使用它的人不是盒子里最锋利的刀,所以我想要使下载尽可能简单。

此刻的代码是:

<button class="downloadButton" type="submit" onClick="window.open('<%=(rsContent.Fields.Item("ContentImage").Value)%>')">Download Image</button>

但这会将图像加载到新窗口/新标签中。

为了记录,用户使用的是带有 Internet Explorer 8 的 Windows XP,所以我们不能使用download html5 事件。

我不介意它是 javascript、JQuery 还是经典的 ASP。

提前感谢您的帮助。

更新

使用发布的 MDN 代码 Lankymart,我按原样尝试,它工作(用于打开/下载 Excel 文档),但是,我尝试更改部件以下载图像,但它没有工作。

这是经典的 ASP 代码:

<%
Dim rsImage__imageID
rsImage__imageID = "1"
If (Request.QueryString("imageID")  <> "") Then 
  rsImage__imageID = Request.QueryString("imageID") 
End If
%>
<%
Dim rsImage
Dim rsImage_cmd
Dim rsImage_numRows

Set rsImage_cmd = Server.CreateObject ("ADODB.Command")
rsImage_cmd.ActiveConnection = MM_ENG_STRING
rsImage_cmd.CommandText = "SELECT ContentID, ContentImage, DisplayImage FROM tblContent WHERE ContentImage = ?" 
rsImage_cmd.Prepared = true
rsImage_cmd.Parameters.Append rsImage_cmd.CreateParameter("param1", 5, 1, -1, rsImage__imageID) ' adDouble

Set rsImage = rsImage_cmd.Execute
rsImage_numRows = 0
%>

以及(严重)更改的 MDN 代码:

<%
'Set the content type to the specific type that you are sending.
Response.ContentType = "image/JPEG"

Const adTypeBinary = 1
Dim strImageFile

strImageFile = (rsImage.Fields.Item("ContentImage").Value) 'This is the path and name of the file on disk. 

Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Open
objStream.Type = adTypeBinary
objStream.LoadFromFile strImageFile

Response.BinaryWrite objStream.Read

objStream.Close
Set objStream = Nothing
%>

我称之为:

<button class="downloadButton" type="submit" onClick="window.location.href='image-download.asp?imageID=<%=(rsContent.Fields.Item("ContentID").Value)%>';">Download Image</button>

它产生的错误是:

The image “http://localhost:85/admin/english/image-download.…p?imageID=5” cannot be displayed because it contains errors.

页面代码为:

<html>

    <head>
        <meta name="viewport" content="width=device-width; height=device-height;"></meta>
        <link rel="stylesheet" href="resource://gre/res/ImageDocument.css"></link>
        <link rel="stylesheet" href="resource://gre/res/TopLevelImageDocument.css"></link>
        <link rel="stylesheet" href="chrome://global/skin/media/TopLevelImageDocument.css"></link>
        <title>

            image-download.asp (JPEG Image)

        </title>
    </head>
    <body>
        <img src="http://localhost:85/admin/english/image-download.asp?imageID=5"  title=""></img>
    </body>

</html>

【问题讨论】:

不能标记为重复 - JavaScript: Prompting user to save file using a 'Save-as' dialog? 但你应该看看这个问题。 自从我发表评论以来,我已经添加了一个答案,因为您可能无法使用 javascript 来做到这一点,但您可以使用图像处理页面来“伪造”它。 现在你已经展示了你已经尝试过的代码,你得到了什么错误?你能把它也包括进去吗? 更新问题并输出错误。 从您非常一般的错误来看,您的代码在哪里失败并不清楚cannot be displayed because it contains errors 不会帮助您调试问题。您是否有在 IIS 中处理 500.100 Internal Server Errors500-100.asp 设置?没有它,您收到的任何错误都不会有意义。 【参考方案1】:

您可以创建一个指向链接的按钮,该链接将图像作为文件返回,它将自动显示保存选项,而不是导航到另一个页面。

在服务器端,指定 mime 类型为 application/octect-stream

【讨论】:

【参考方案2】:

更新 - 与问题中的 cmets 相关

您可能还会发现需要包含

Response.AddHeader("Content-Length", LenB(yourbinary))

阻止某些浏览器无法验证有效负载。如果您不确定使用,ContentType 与发送的内容相匹配也很重要

Response.Content = "application/octet-stream"

无法通过 javascript 从浏览器启动“另存为”对话框,但您可以通过在 Content-Disposition HTTP 标头中设置 attachment 值来伪造浏览器以显示“另存为”对话框。

我解决这个问题的方法是使用 ASP 页面生成图像(通过 COM 组件、ADODB.Stream、数据库 blob 等),您可以使用这种方式;

Response.AddHeader("Content-Disposition", "attachment;filename=myimage.jpg")

这将强制保存图像而不是内联显示。因此,使用这样的脚本,您可以将一个查询字符串值传递给它以显示内联(查看图像时),并将其强制为附件,这将强制另存为对话框(浏览器行为可能略有不同)。

流式传输到浏览器

使用ADODB.Stream 对象将文件输出到浏览器。

Return an image using ASP, not .NET (堆栈溢出) How To Use the ADODB.Stream Object to Send Binary Files to the Browser through ASP (微软支持)

过去,我使用 javascript 启动了“另存为”对话框(但没有什么能阻止您使用 HTML 锚标记在没有任何 javascript 的情况下执行相同的操作);

/* 
passing myimageid is a way of identifying the image to return 
be it a database or file system lookup.
*/
window.location.href = "/myimage.asp?id=myimageid&display=attachment";

因为响应是作为附件返回的,所以位置实际上从未更改,并且会立即显示“另存为”对话框,其中包含从文件名框中的 Content-Disposition HTTP 标头传递的文件名。

【讨论】:

谢谢。您的回答远远超出我的想象,但我正在尝试,所以,只有几个问题。 1)。该站点位于托管站点上,这仍然可以吗? 2)。 MDN 声明“添加标头后,将无法删除。”这是否会影响所有图像,因为某些图像(不在管理站点上)是灯箱的一部分? @MartySmartyPants 您无需更改源图像的标题,您所做的是构建一个输出为 Content-Type: image/jpeg 的 ASP 页面,然后使用类似 @ 的东西将图像输入 ASP 页面987654333@ 对象。该链接应该会有所帮助。 对不起,我应该把 MDN 语句放在上下文中。它指的是 HTTP 标头而不是图像。 @MartySmartyPants 我明白了。我想说的是,在刷新响应缓冲区之前不会写入您的 HTTP 标头。通常的方法是 1.Response.ContentType = "&lt;your mime type&gt;" 2.将你的文件/db blob 拉入ADODB.Stream 3.使用Response.BinaryWrite(yourbinary) 输出响应缓冲区。您可以在第 3 步之前的任何步骤添加标题。一旦您这样做,您的标题将被写入并且无法更改。 我已经更新了问题,非常感谢您的帮助。谢谢。

以上是关于打开“另存为”对话框以下载图像的主要内容,如果未能解决你的问题,请参考以下文章

Chrome 扩展程序中未显示另存为对话框

不考虑另存为文件类型的另存为通用文件对话框

“另存为”对话框文件名

ASP.NET 中 IE 7,8 中“另存为”对话框的问题

另存为Dailog,不会弹出

Firefox 3.x 扩展:对话框“另存为”-选择开启器,如何打开?