2010-10-22 4 views
1

donc un navigateur Android ou WebView fonctionne très bien avec urls comme ça - abc.com/xyz.txtNavigateur Android/bug de webview? Contenu-Disposition: attachement; filename = "xyz.txt"

Cependant, si votre URL ressemble à ceci - abc.com/xyz.php et ce qui est envoyé au navigateur dans les en-têtes est - Content-Disposition: attachment; filename = "xyz.txt", alors les navigateurs Android et la vue web semblent devenir terriblement confus.

Il semble qu'il enregistre le nom de fichier correct sur le téléphone, mais le contenu est rempli avec la page Web précédemment affichée. Cela fonctionne parfaitement sur les navigateurs basés sur PC et sur un iPhone et un Blackberry, c'est seulement un problème sur les versions Android 2.1 et 2.2 (n'en ai pas testé d'autres).

Quelqu'un at-il une solution? Sera très reconnaissant. Je vraiment ne veux pas commencer à stocker des fichiers statiques et que vous souhaitez générer mon contenu de téléchargement à la volée. Le journal sur le téléphone n'a révélé aucun indice.


Voici ce qui est envoyé par le serveur au navigateur

===================== start content ==================================== 
HTTP/1.1 200 OK 
Date: Thu, 21 Oct 2010 21:22:11 GMT 
Server: Apache 
Content-Disposition: attachment; filename="Wafty.txt" 
Content-length: 30 
Content-Type: text/plain; charset=ISO-8859-1 

Hello this is a test of a file 
========= There was no carriage return at the end of the above line ==== 
+0

Générez votre contenu de téléchargement à la volée, stocké dans un fichier temporaire et adressez-lui une redirection 301. Nettoyez le contenu généré via un travail cron/une tâche planifiée. Cela peut être gênant - c'est juste une pensée. – CommonsWare

+3

@CommonsWare: Cela choque mes sensibilités! :-) –

+0

Essayez de modifier Content-Type en 'application/octet-stream'. – clu3Less

Répondre

1

utilisation

Content-Disposition: attachment;filename="xyz.txt" 

ne pas utiliser

Content-Disposition: attachment; filename="xyz.txt" 
+0

J'ai plusieurs services Web et cet espace ne pose aucun problème. Voici un exemple d'en-tête de réponse: Content-Disposition: attachment; filename = "test.txt" – Sal

1

J'ai un problème semblable à la vôtre. Le problème ici est de savoir comment WebView gère les pièces jointes (une vraie douleur dans le cul). Lorsque le WebView visite une page Web qui renvoie à un moment donné une pièce jointe, il dit un peu comme "Oh merde, que puis-je faire avec ce truc non-HTML? ... Ey vous! DownloadListener! Faire quelque chose avec cette URL qui dit un non-sens à propos d'un attachement ". Ainsi, le DownloadListener prend le relais et voici le problème: il demande à nouveau la même URL pour télécharger la pièce jointe, donc, pour télécharger une pièce jointe lors de la visite d'une page, le WebView effectue 2 requêtes: la page elle-même et une autre pièce jointe, au lieu de simplement le télécharger.

Et comment est-ce un problème? Eh bien, disons que dans votre abc.com/xyz.php vous avez une certaine logique comme:

<?php 
    if(User::loggedIn()) { 
     header("Content-Disposition: attachment..."); 
     //Some more logic for the download 
    } 
?> 

La deuxième demande effectuée par le DownloadListener fera une autre demande à abc.com/xyz.php~~V~~3rd, mais cette fois-ci ne contiendra pas de cookies ni d'informations sur la session, de sorte qu'il n'entrera pas dans la logique de "téléchargement".

Une solution possible serait de rediriger vers une copie temporelle ou le chemin réel vers le fichier qui ne contient aucune logique, donc il n'y a pas de problème. Bien sûr, vous devez également définir votre écouteur de téléchargement avec votre WebView, quelque chose comme ceci par exemple.

webView.setDownloadListener(new DownloadListener() { 

    @Override 
    public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimeType, long contentLength) { 

     final DownloadManager dm = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); 
     Request request = new DownloadManager.Request(Uri.parse(url)); 
     request.setMimeType(mimeType); 

     //Persist download notification in the status bar after the download completes (Android 3.0+) 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 
      request.allowScanningByMediaScanner(); 
      request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); 
     } 

     dm.enqueue(request); 
    } 

}); 
Questions connexes