Предотвращение проблем с типом контента при загрузке файла через браузер на Android - PullRequest
15 голосов
/ 13 января 2011

Если у меня есть файл, доступный для браузера через мое веб-приложение, я обычно просто задаю URL-адрес, например, http://website.com/webapp/download/89347/image.jpg.Затем я устанавливаю заголовки HTTP Content-Type: application/octet-stream; filename=image.jpg и Content-Disposition: Attachment.

Однако на Android.Кажется, единственный способ получить файл для загрузки - установить Content-Type: image/jpg.В противном случае имя файла говорит <Unknown> и появляется ошибка

Загрузка не удалась
Невозможно загрузить.Содержимое на этом телефоне не поддерживается

Можно ли как-нибудь заставить Android загрузить и открыть файл через браузер без сохранения списка типов пантомимы?

Ответы [ 5 ]

24 голосов
/ 20 апреля 2011

Чтобы все загрузки работали на всех (и особенно старых) версиях Android должным образом, вам необходимо ...

  1. установить для ContentType значение application / octet-stream
  2. поместите значение имени файла Content-Disposition в двойные кавычки
  3. напишите расширение имени файла Content-Disposition в UPPERCASE

Прочтите мой блог для получения более подробной информации:
http://digiblog.de/2011/04/19/android-and-the-download-file-headers/

10 голосов
/ 20 декабря 2011

Дмитрий (или другие, которые ищут возможное решение), если в загруженном файле появляется html-страница, я подозреваю, что это связано с двойной проблемой HttpRequest GET. Типичным сценарием является следующая модель POST, Redirect, GET:

  • Браузер Android выдает POST-запрос HttpRequest на сервер (например, кнопка отправки или ссылка для запроса файла загрузки, имя файла.ext скажем)

  • Сервер направляет запрошенный файл filename.ext в байты, сохраняет его в переменной сеанса и затем выдает Response.Redirect для Download.aspx, например, для обработки конструкции объекта ответа

  • Браузер Android корректно отправляет HttpRequest GET на сервер для загрузки .aspx

  • Сервер отвечает типичным Content-Disposition: вложением; Конструкция стиля filename = "filename.ext" с объектом ответа, содержащим запрошенный filename.ext, который является байтами в переменной сеанса.

  • Менеджер загрузок Android, я полагаю, затем отправляет еще один запрос HttpRequest GET на сервер для Download.aspx. Я подозреваю, что менеджер загрузок интерпретирует предыдущий ответ «вложение» как триггер для отправки этого второго GET.

  • Сервер (Download.aspx) снова пытается создать объект ответа для отправки обратно в браузер.

  • Менеджер загрузки Android загружает файл filename.ext, используя содержимое объекта ответа из второго файла Download.aspx.

Во многих случаях это было бы хорошо. Но если, например, сервер в коде Download.aspx выполняет некоторую служебную работу и удаляет переменную сеанса при первом ее вызове, то в следующий раз переменная сеанса отсутствует. Таким образом, в зависимости от того, как написан код, возможно, что объект ответа не получит ясности и, возможно, не будет вызван Response.End, и в результате отправляется только HTML-файл Download.aspx.

Это то, что мы обнаружили с помощью Wireshark, хотя, признаюсь, я предполагаю, что причиной двойного GET является менеджер загрузок Android.

Надеюсь, это объяснение помогло.

2 голосов
/ 25 ноября 2013

Как я писал при скачивании файлов с андроида :

Браузер 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.
0 голосов
/ 20 декабря 2011

Теоретически, параметр имени файла должен быть установлен на Content-Disposition, а не Content-Type. Не уверен, поможет ли это браузеру Android.

0 голосов
/ 17 июля 2011

Я перепробовал все рекомендации из блога Jspy, но пока ничего не получалось. Контент-расположение переводит браузер в режим загрузки, однако ничего не загружается, кроме HTML страницы, с которой началась загрузка. Итак, мой вывод, это чисто ошибка от Google, и мы можем только молиться за то, чтобы Google это исправил. Моя работа заключалась в том, чтобы установить тип контента для какого-либо типа, поступающего из мобильного браузера в форме заголовка Accept. Обычно это работает, вы даже можете загружать zip-файлы в виде текста.

...