17

如果我有一个文件可以通过我的 web 应用程序提供给浏览器,我通常只需将 URL 设置为类似http://website.com/webapp/download/89347/image.jpg. 然后我设置 HTTP 标头Content-Type: application/octet-stream; filename=image.jpgContent-Disposition: Attachment.

但是,在安卓上。似乎我可以下载文件的唯一方法是设置Content-Type: image/jpg. 否则文件名<Unknown>会出现错误

下载失败
无法下载。此手机不支持该内容

有什么方法可以让Android通过浏览器下载和打开文件而不保留mime类型列表?

4

5 回答 5

27

要使任何下载按预期在所有(尤其是较旧的)Android 版本上运行,您需要...

  1. 将 ContentType 设置为 application/octet-stream
  2. 将 Content-Disposition 文件名值放在双引号中
  3. 以大写形式编写 Content-Disposition 文件扩展名

阅读我的博客文章了解更多详情:
http ://digiblog.de/2011/04/19/android-and-the-download-file-headers/

于 2011-04-20T10:28:28.553 回答
10

Dmitriy(或其他寻找可能解决方案的人)如果您下载的文件中出现 html 页面,我怀疑这是由于双重 HttpRequest GET 问题。一个典型的场景是下面的 POST、Redirect、GET 模型:

  • Android 浏览器向服务器发出 HttpRequest POST(例如提交按钮或链接以请求下载文件,例如 filename.ext)

  • 服务器将请求的 filename.ext 流式传输到字节,存储在会话变量中,然后向 Download.aspx 发出 Response.Redirect,例如,处理响应对象构造

  • Android 浏览器正确地向服务器发送 HttpRequest GET 以获取 Download.aspx

  • 服务器以典型的 Content-Disposition 响应:附件;filename="filename.ext" 样式构造,响应对象包含请求的 filename.ext,即会话变量中的字节。

  • 我相信,Android 下载管理器会向服务器发送另一个 HttpRequest GET 以获取 Download.aspx。我怀疑下载管理器将先前的“附件”响应解释为发送第二个 GET 的触发器。

  • 服务器 (Download.aspx) 再次尝试构造响应对象以发送回浏览器。

  • Android 下载管理器使用来自第二个 Download.aspx 的响应对象内容下载 filename.ext。

在许多情况下,这会很好。但是,如果,例如,Download.aspx 代码中的服务器在第一次调用时进行了一些内务处理并删除了会话变量,那么下次就没有会话变量了。因此,根据代码的编写方式,可能没有明确构造响应对象,也可能没有调用 Response.End,因此最终只发送了 Download.aspx 的 html。

这是我们使用 Wireshark 发现的,尽管我承认我假设它是导致双重 GET 的原因是 Android 下载管理器。

我希望这个解释有所帮助。

于 2011-12-20T17:07:59.930 回答
2

正如我在从 android 下载文件时所写:

Android 浏览器不会在按钮发布事件中下载文件。在发布事件中,该文件将是一些 .htm 垃圾文件。完成此操作如下。

在下载按钮中单击

 protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
    {
        Response.Redirect("download-file.aspx");
    }

and on  download-file.aspx file do as below

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class mobile_download_file : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string filename = "usermanual.pdf";
        Response.ContentType = "application/octet-stream";
        Response.AppendHeader("Content-Disposition", "attachment; filename=" + "" + filename + "");
        Response.Write(Server.MapPath(Request.ApplicationPath) + "\\" + filename);
        Response.TransmitFile(Server.MapPath(Request.ApplicationPath) + "\\" + filename);
        Response.End();
    }
}

the same can be implemented in php also.
于 2013-11-25T05:31:17.043 回答
0

我已经尝试了来自 Jspy 博客的所有建议,但到目前为止没有任何效果。Content-disposition 使浏览器处于下载模式,但是除了启动下载的页面的 HTML 之外,什么都没有下载。所以我的结论是,这纯粹是谷歌的错误,我们只能祈祷谷歌修复它。我的解决方法是将内容类型设置为来自接受标题表单移动浏览器的某种类型。它通常可以工作,您甚至可以将 zip 文件下载为文本。

于 2011-07-17T01:21:06.583 回答
0

理论上,文件名参数应该设置在 Content-Disposition 上,而不是 Content-Type 上。不确定这是否对 Android 浏览器有帮助。

于 2011-12-20T18:06:59.893 回答