【问题标题】:Avoiding content type issues when downloading a file via browser on Android在 Android 上通过浏览器下载文件时避免内容类型问题
【发布时间】:2011-06-08 03:59:27
【问题描述】:

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

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

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

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

【问题讨论】:

  • 您好 George,我正在使用相同的技术制作下载链接,但我不明白如何在为锚标签准备下行链接时设置“HTTP 标头”?你能解释一下吗?
  • 设置 HTTP 标头是在 Web 服务器上的服务器端完成的,通常使用 PHP、Java、CGI 等编程语言。您如何提供要下载的文件?
  • 请记住,这是一篇较早的帖子,引用了一些较早的 android 版本,并且可能包含过时的信息。 Content-Disposition 通常用于指示请求下载,而不仅仅是“查看”。

标签: android browser download content-type content-disposition


【解决方案1】:

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

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

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

【讨论】:

  • 如果您遇到设备下载 html 页面而不是正确文件的情况,请参阅 StevePayne 的回答。我通过将 POST 更改为 GET 解决了这个问题。
  • 你好,如果我从 downloadmanager 下载图像,那么它再次无法打开,错误无法打开文件。我已将请求的模拟类型设置为 jpg。我还需要做什么
  • Android 4,冰淇淋三明治。示例:Content-Disposition: attachment; filename="MyFileName.ZIP"; 将无法正常工作,因为末尾有分号。所有 Android 版本的任何测试(和总结)?有用的:stackoverflow.com/questions/6319389/…Google Chrome v12 release introduced a bug that triggers the problem you describe. You can fix it by sending the Content-Length headerbugs.chromium.org/p/chromium/issues/detail?id=85549
  • #3 是绝对需要的。我已将服务器设置为发送我自己的 mimetype,但当我将文件扩展名更改为大写时,android 仍将其保存为 application/octet-stream。
  • 感谢@kuchi 的反馈。我不敢相信这些东西仍然有意义。当我在 2011 年写这篇文章时,我们使用的是 Android 2.1 !!!
【解决方案2】:

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 下载管理器。

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

【讨论】:

  • 史蒂夫,您的解释与我博客文章评论者的观察非常吻合(在我上面的回答中提到)。即使使用更高的 Android 版本(至少高达 3.2.1),这个问题似乎也会发生,并且似乎取决于使用的浏览器(Dolphin 和 Android 库存受影响,FF 和 Opera 不受影响)。一种可能的解决方案是用 GET 替换第一个请求或将所有需要的数据(如果可能)编码到下载请求的 URL 中。干杯,约尔格。
  • 我在 Android 论坛中发现了问题 17803948,它们描述了 stock 浏览器和 Android 下载管理器无法正确处理通过 POST 请求启动的下载。两份报告都得到了论坛版主的认可,但被标记为“增强”而不是错误。 1780 已有 3 年多的历史,被 +100 位访问者加注星标,但仍然没有迹象表明它已解决,即使在最新的 Android 版本(目前为 4.0.4)中也没有。
  • 有人找到解决方案了吗?这仍然是有效的问题。下载期间我在服务器上收到两个请求。是否有可能找出哪个请求是假的?
【解决方案3】:

正如我在downloading files from 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.

【讨论】:

  • 您好 Martin,欢迎来到 StackOverflow。 1.我不认为POST请求是问题的一部分,但这并不重要,也许你的回答对某些人有帮助。 2.我认为代码示例与这里无关。 我不使用 php 或 aspx。。 3. 我建议编辑将代码示例替换为诸如“您需要创建一个重定向作为对 POST 的响应,然后从您重定向到的 URL 下载文件”之类的文本。那些寻找代码示例的人应该针对他们的语言发布一个问题。
  • 您测试了哪些 Android 版本
【解决方案4】:

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

【讨论】:

  • Dmitriy,如果您的 Android 下载源(!)页面的 HTML,那么您的服务器脚本逻辑肯定有问题。如果在 Android 端下载失败,则不可能在文件中包含源 HTML - 通常您会获得下载内容但不会写入文件或一般错误消息。但在那个时间点,源 HTML 不可用。想想吧。
【解决方案5】:

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

【讨论】:

    猜你喜欢
    • 2017-10-06
    • 1970-01-01
    • 2012-03-28
    • 2012-09-14
    • 1970-01-01
    • 2012-08-26
    • 2021-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多