Frage

Ich habe eine einfache Datei-Upload-Download-Mechanismus implementiert. Wenn ein Benutzer einen Dateinamen klickt, wird die Datei mit diesen HTTP-Header heruntergeladen wird:

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

Ich unterstütze auch japanische Dateinamen. Um das zu tun, kodieren ich den Dateinamen mit dieser Java-Methode:

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");
}

Es funktionierte gut, so weit, bis jemand herausgefunden, dass es nicht gut mit langen Dateinamen funktioniert. Zum Beispiel: あああああああああああああああ2008.10.1あ.doc. Wenn ich einen der Single-Byte-Punkte zu einem Single-Byte-Unterstreichungs ändern, oder wenn ich das erste Zeichen zu entfernen, funktioniert es OK. das heißt, es hängt von der Länge und URL-Codierung eines Punktzeichen. Im Folgenden sind einige Beispiele.

Dies ist gebrochen (あああああああああああああああ2008.10.1あ.doc):

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;

Das ist in Ordnung (あああああああああああああああ2008_10.1あ.doc):

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;

Das ist auch in Ordnung (あああああああああああああああ2008.10.1あ.doc):

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;

Wer eine Ahnung haben?

War es hilfreich?

Lösung

gmail behandelt Dateinamen etwas anders zu entkommen: der Dateiname (doppelte Anführungszeichen) zitiert wird, und Single-Byte-Perioden sind nicht URL-escaped. Auf diese Weise ist die langen Dateinamen in der Frage 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"

Es gibt jedoch noch eine Begrenzung (scheinbar IE-only) auf der Byte-Länge des Dateinamens (ein Fehler, gehe ich davon aus). Also selbst wenn der Dateiname nur Single-Byte-Zeichen gemacht wird, wird der Anfang des Dateinamen abgeschnitten. Die Begrenzung liegt bei etwa 160 Byte.

Andere Tipps

Wie oben erwähnt, Content-Disposition und Unicode unmöglich ist, alles Haupt-Browser zum Laufen zu bringen, ohne Browser-Sniffing und andere Header für jede Rückkehr.

war meine Lösung, um die Content-Disposition-Header vollständig, und fügen Sie den Dateinamen an das Ende der URL zu vermeiden, um den Browser verleiten zu denken, es wurde direkt eine Datei zu bekommen. z.

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

Dies setzt natürlich voraus, dass Sie den Dateinamen kennen, wenn Sie den Link zu erstellen, obwohl eine schnelle Weiterleitung Header auf Nachfrage einstellen könnte.

Das Hauptproblem dabei ist, dass IE nicht die entsprechende RFC nicht unterstützt, hier: RFC2231. Siehe Zeiger und Testfälle . Darüber hinaus ist die Abhilfe, die Sie für den Internet Explorer verwenden (nur mit Prozent-escaped UTF-8) mehrere zusätzliche Probleme hat; es kann nicht in allen lokalen Umgebungen arbeiten (soweit ich mich erinnere, das Verfahren in Korea schlägt fehl, wenn IE immer so konfiguriert ist, UTF-8 in URLs zu verwenden, die nicht der Standard ist), und, wie bereits erwähnt, gibt es Längenbegrenzungen (I hören, dass , dass ist in IE8 festgelegt, aber ich habe nicht versucht noch) nicht.

Ich denke, das Problem in IE8 festgelegt ist, habe ich es gesehen in IE 8 zu arbeiten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top