Question

J'ai mis en place un mécanisme simple de téléchargement de fichier. Lorsqu'un utilisateur clique sur un nom de fichier, le fichier est téléchargé avec les en-têtes HTTP suivants:

HTTP/1.1 200 OK
Date: Tue, 30 Sep 2008 14:00:39 GMT
Server: Microsoft-IIS/6.0
Content-Disposition: attachment; filename=filename.doc;
Content-Type: application/octet-stream
Content-Length: 10754

Je supporte également les noms de fichiers japonais. Pour ce faire, je code le nom du fichier avec cette méthode java:

private String encodeFileName(String name) throws Exception{
    String agent = request.getHeader("USER-AGENT");
    if(agent != null && agent.indexOf("MSIE") != -1){ // is IE
        StringBuffer res = new StringBuffer();
        char[] chArr = name.toCharArray();
        for(int j = 0; j < chArr.length; j++){
            if(chArr[j] < 128){ // plain ASCII char
                if (chArr[j] == '.' && j != name.lastIndexOf("."))
                    res.append("%2E");
                else
                    res.append(chArr[j]);
            }
            else{ // non-ASCII char
                byte[] byteArr = name.substring(j, j + 1).getBytes("UTF8");
                for(int i = 0; i < byteArr.length; i++){
                    // byte must be converted to unsigned int
                    res.append("%").append(Integer.toHexString((byteArr[i]) & 0xFF));
                }
            }
        }
        return res.toString();
    }
    // Firefox/Mozilla
    return MimeUtility.encodeText(name, "UTF8", "B");
}

Cela a bien fonctionné jusqu'à ce que quelqu'un découvre que cela ne fonctionne pas bien avec les noms de fichiers longs. Par exemple: 2008.10.1 ? .doc . Si je modifie l'un des points à un octet en un soulignement à un octet ou si je supprime le premier caractère, cela fonctionne correctement. c'est-à-dire que cela dépend de la longueur et du codage d'URL d'un point. Voici quelques exemples.

Ceci est cassé (), :

Content-Disposition: attachment; filename=%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%822008%2E10%2E1%e3%81%82.doc;

Ceci est OK ( 2008_10.1). :

Content-Disposition: attachment; filename=%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%822008_10%2E1%e3%81%82.doc;

C’est également correct (), :

Content-Disposition: attachment; filename=%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%82%e3%81%822008%2E10%2E1%e3%81%82.doc;

Quelqu'un a-t-il un indice?

Était-ce utile?

La solution

gmail traite le nom de fichier d'échappement de manière quelque peu différente: le nom de fichier est entre guillemets, et les périodes d'un octet ne sont pas échappées par une URL. De cette façon, le nom de fichier long dans la question est OK.

Content-Disposition: attachment; filename="%E3%81%82%E3%81%82%E3%81%82%E3%81%82%E3%81%82%E3%81%82%E3%81%82%E3%81%82%E3%81%82%E3%81%82%E3%81%82%E3%81%82%E3%81%82%E3%81%82%E3%81%822008.10.1%E3%81%82.doc"

Cependant, il y a toujours une limitation (apparemment pour IE uniquement) sur la longueur en octets du nom du fichier (un bogue, je suppose). Ainsi, même si le nom de fichier est composé uniquement de caractères à un octet, le début du nom de fichier est tronqué. La limite est d'environ 160 octets.

Autres conseils

Comme mentionné ci-dessus, Content-Disposition et Unicode sont impossibles à faire fonctionner tous les principaux navigateurs sans renifler le navigateur et renvoyer des en-têtes différents pour chacun.

Ma solution consistait à éviter complètement l'en-tête Content-Disposition et à ajouter le nom du fichier à la fin de l'URL pour inciter le navigateur à penser qu'il récupérait directement un fichier. par exemple

http://www.xyz.com/cgi-bin/dynamic.php/あああああああああああああああ2008.10.1あ.doc

Cela suppose naturellement que vous connaissiez le nom du fichier lorsque vous créez le lien, bien qu'un en-tête de redirection rapide puisse le définir à la demande.

Le principal problème ici est que IE ne prend pas en charge la RFC correspondante, ici: RFC2231. Consultez les pointeurs et scénarios de test . En outre, la solution de contournement que vous utilisez pour IE (en utilisant uniquement le format d'écriture UTF-8 à pourcentage d'échappement) présente plusieurs problèmes supplémentaires. cela peut ne pas fonctionner dans toutes les langues (autant que je me souvienne, la méthode échoue en Corée à moins que IE soit configuré pour toujours utiliser UTF-8 dans des URL qui ne sont pas la valeur par défaut), et, comme mentionné précédemment, il existe des limites de longueur (I entendre que ce est corrigé dans IE8, mais je n'ai pas encore essayé).

Je pense que ce problème est résolu dans IE8, je l'ai déjà vu fonctionner dans IE 8.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top