Domanda

Ho implementato un semplice meccanismo di upload-download dei file. Quando un utente fa clic sul nome di un file, il file viene scaricato con queste intestazioni HTTP:

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

Supporta anche nomi di file giapponesi. Per fare ciò, codifico il nome del file con questo metodo 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");
}

Finora ha funzionato bene, fino a quando qualcuno ha scoperto che non funziona bene con nomi di file lunghi. Ad esempio: & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354 2008/10/01; .doc . Se cambio uno dei punti a byte singolo in una sottolineatura a byte singolo, o se rimuovo il primo carattere, funziona bene. cioè, dipende dalla lunghezza e dalla codifica URL di un carattere punto. Di seguito sono riportati alcuni esempi.

Questo è rotto ( & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354 2008/10/01; .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;

Questo è OK ( & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354 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;

Anche questo va bene ( & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354 ; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354; & # 12354 2008/10/01; .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;

Qualcuno ha un indizio?

È stato utile?

Soluzione

gmail gestisce l'escape del nome del file in modo leggermente diverso: il nome del file è tra virgolette (virgolette doppie) e i periodi a byte singolo non sono sottoposti a escape con URL. In questo modo, il nome del file lungo nella domanda è 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"

Tuttavia, esiste ancora una limitazione (apparentemente solo IE) sulla lunghezza in byte del nome del file (un bug, presumo). Pertanto, anche se il nome del file è composto da soli caratteri a byte singolo, l'inizio del nome del file viene troncato. La limitazione è di circa 160 byte.

Altri suggerimenti

Come accennato in precedenza, Content-Disposition e Unicode è impossibile far funzionare tutti i browser principali senza annusare il browser e restituire intestazioni diverse per ciascuno.

La mia soluzione era evitare completamente l'intestazione Content-Disposition e aggiungere il nome file alla fine dell'URL per indurre il browser a pensare che stesse ottenendo direttamente un file. per es.

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

Ciò presuppone naturalmente che tu conosca il nome del file quando crei il collegamento, anche se un'intestazione di reindirizzamento rapido potrebbe impostarlo su richiesta.

Il problema principale qui è che IE non supporta la RFC pertinente, qui: RFC2231. Vedi puntatori e casi di test . Inoltre, la soluzione alternativa che si utilizza per IE (utilizzando solo UTF-8 con escape percentuale) presenta diversi problemi aggiuntivi; potrebbe non funzionare in tutte le versioni locali (per quanto ricordo, il metodo non funziona in Corea a meno che IE non sia configurato per utilizzare sempre UTF-8 negli URL che non è l'impostazione predefinita) e, come accennato in precedenza, ci sono limiti di lunghezza (I sento che che è stato corretto in IE8, ma non ho ancora provato).

Penso che questo problema sia stato risolto in IE8, l'ho visto funzionare in IE 8.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top