HTTP'de Content-Disposition üstbilgisinin dosyaadı parametresi nasıl kodlanır?


535

Bir kaynağı doğrudan bir Web tarayıcısında oluşturulmak yerine indirilmeye zorlamak isteyen web uygulamaları , formun HTTP yanıtında bir başlık oluşturur:Content-Disposition

Content-Disposition: attachment; filename=FILENAME

filenameParametre kaynak tarayıcı tarafından indirilen içine dosya için bir ad önermek için kullanılabilir. Bununla birlikte, RFC 2183 (Content-Disposition) bölüm 2.3'te (Dosya Adı Parametresi) dosya adının yalnızca US-ASCII karakterlerini kullanabileceğini belirtir:

Geçerli [RFC 2045] dilbilgisi, parametre değerlerini (ve dolayısıyla İçerik İmhası dosya adlarını) US-ASCII ile sınırlar. Dosya adlarında rastgele karakter kümelerine izin verilmesinin büyük bir arzu duyulduğunu biliyoruz, ancak gerekli mekanizmaları tanımlamak bu belgenin kapsamı dışındadır.

Bununla birlikte, günümüzde en popüler Web tarayıcılarının ABD-ASCII olmayan karakterlere (standart olmaması nedeniyle) dosya adının kodlama şemasına ve karakter seti spesifikasyonuna katılmadığına dair ampirik kanıtlar vardır. Öyleyse soru, “naïffile” dosya adının (tırnak işaretleri olmadan ve üçüncü harfin U + 00EF olduğu) İçerik-Disposition başlığına kodlanması gerekiyorsa, popüler tarayıcılar tarafından kullanılan çeşitli şemalar ve kodlamalar nelerdir?

Bu sorunun amacı için, popüler tarayıcılar :

  • Firefox
  • Internet Explorer
  • Safari
  • Google Chrome
  • Opera

Mobile Safari (@Martin Ørding-Thomsen tarafından önerildiği gibi ham utf-8) için çalıştım, ancak aynı cihazdan GoodReader için çalışmaz. Herhangi bir fikir?
Thilo


1
Eğer yolun son segmentini ayarlayabilirseniz, Kornel'in cevabı en az direnç yolu oldu; çift ​​bunu Content-Disposition: attachment.
Antti Haapala

Yanıtlar:


94

Önerilen RFC 5987 , "Köprü Metni Aktarım Protokolü (HTTP) Üstbilgi Alanı Parametreleri için Karakter Kümesi ve Dil Kodlaması" nda tarayıcı sınaması ve geriye dönük uyumluluk bağlantıları da dahil olmak üzere bununla ilgili bir tartışma vardır .

RFC 2183 , bu başlıkların , yukarıdaki taslak RFC tarafından kapsanan RFC 2231 tarafından kullanılmayan RFC 2184'e göre kodlanması gerektiğini belirtir .


5
Ayrıca internet taslağının ("taslak RFC" değil) tamamlandığını ve son belgenin RFC 5987 olduğunu ( greenbytes.de/tech/webdav/rfc5987.html )
Julian Reschke

11
Bununla ilgili olarak, dosya adında virgül (,) varsa Firefox'un (sürüm 4-9 dahil) kırıldığını keşfettim Content-Disposition: filename="foo, bar.pdf". Sonuç olarak, firefox dosyayı doğru bir şekilde indirir ancak .partuzantıyı korur (örn. foo,bar.pdf-1.part). Daha sonra, uygulama ilişkilendirilmediğinden, dosya doğru şekilde açılmaz .part. Diğer ASCII karakterleri düzgün çalışıyor gibi görünüyor.
catchdave

3
IE davranışı hakkında daha fazla bilgi için bkz. Blogs.msdn.com/b/ieinternals/archive/2010/06/07/…
EricLaw

5
@catchdave: "Eki" unuttun; Bölüm.
Christoffer Hammarström

6
Sonuçta, bu 74 upvotes ile sadece bağlantı bir cevaptan başka bir şey değildir.
Antti Haapala

364

Bu eski bir yazı olduğunu biliyorum ama yine de çok alakalı. Modern tarayıcıların utf-8 kodlamasına, yüzde kodlamasına (url kodlu) izin veren rfc5987'yi desteklediğini buldum. Sonra saf file.txt olur:

Content-Disposition: attachment; filename*=UTF-8''Na%C3%AFve%20file.txt

Safari (5) bunu desteklemiyor. Bunun yerine, dosya adını doğrudan utf-8 kodlu başlığınıza yazmak için Safari standardını kullanmalısınız:

Content-Disposition: attachment; filename=Naïve file.txt

IE8 ve daha eski sürümleri de desteklemez ve utf-8 kodlamasının IE standardını kullanmanız gerekir, yüzde kodlanmış:

Content-Disposition: attachment; filename=Na%C3%AFve%20file.txt

ASP.Net'te aşağıdaki kodu kullanıyorum:

string contentDisposition;
if (Request.Browser.Browser == "IE" && (Request.Browser.Version == "7.0" || Request.Browser.Version == "8.0"))
    contentDisposition = "attachment; filename=" + Uri.EscapeDataString(fileName);
else if (Request.Browser.Browser == "Safari")
    contentDisposition = "attachment; filename=" + fileName;
else
    contentDisposition = "attachment; filename*=UTF-8''" + Uri.EscapeDataString(fileName);
Response.AddHeader("Content-Disposition", contentDisposition);

Yukarıdakileri IE7, IE8, IE9, Chrome 13, Opera 11, FF5, Safari 5 kullanarak test ettim.

Kasım 2013 Güncellemesi :

İşte şu anda kullandığım kod. Hala IE8'i desteklemeliyim, bu yüzden ilk kısımdan kurtulamıyorum. Android'deki tarayıcıların yerleşik Android indirme yöneticisini kullandıkları ve dosya adlarını standart şekilde güvenilir bir şekilde ayrıştıramadığı ortaya çıkıyor.

string contentDisposition;
if (Request.Browser.Browser == "IE" && (Request.Browser.Version == "7.0" || Request.Browser.Version == "8.0"))
    contentDisposition = "attachment; filename=" + Uri.EscapeDataString(fileName);
else if (Request.UserAgent != null && Request.UserAgent.ToLowerInvariant().Contains("android")) // android built-in download manager (all browsers on android)
    contentDisposition = "attachment; filename=\"" + MakeAndroidSafeFileName(fileName) + "\"";
else
    contentDisposition = "attachment; filename=\"" + fileName + "\"; filename*=UTF-8''" + Uri.EscapeDataString(fileName);
Response.AddHeader("Content-Disposition", contentDisposition);

Yukarıdakiler şimdi indirmek için bu dosya adını kullanarak IE7-11, Chrome 32, Opera 12, FF25, Safari 6'da test edildi: 你好 abcABCæøåÆØÅäöüïëêîâéíáóúýñ½§! # ¤% & () = `@ @ £ $ € {[]} + ´¨ ^ ~ '-_;. txt

IE7'de tüm karakterler için değil, bazı karakterler için çalışır. Ama günümüzde IE7'yi kim önemsiyor?

Bu, Android için güvenli dosya adları oluşturmak için kullandığım işlevdir. Android'de hangi karakterlerin desteklendiğini bilmediğimi ancak bunların kesin olarak çalıştığını test ettiğimi unutmayın:

private static readonly Dictionary<char, char> AndroidAllowedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ._-+,@£$€!½§~'=()[]{}0123456789".ToDictionary(c => c);
private string MakeAndroidSafeFileName(string fileName)
{
    char[] newFileName = fileName.ToCharArray();
    for (int i = 0; i < newFileName.Length; i++)
    {
        if (!AndroidAllowedChars.ContainsKey(newFileName[i]))
            newFileName[i] = '_';
    }
    return new string(newFileName);
}

@TomZ: IE7 ve IE8'de test ettim ve kesme işaretinden (') kaçmak zorunda olmadığım ortaya çıktı. Başarısız olduğu bir örneğiniz var mı?

@Dave Van den Eynde: Android ve IE7 + 8 dışında RFC6266'ya uygun olarak iki dosya adını bir satırda birleştirerek bunu yansıtacak kodu güncelledim. Öneri için teşekkürler.

@Thilo: GoodReader veya diğer tarayıcı olmayanlar hakkında hiçbir fikrim yok. Android yaklaşımını kullanma şansınız olabilir.

@Alex Zhukovskiy: Nedenini bilmiyorum ama Connect'te tartışıldığı gibi çok iyi çalışmıyor gibi görünüyor.


1
Mobile Safari (yukarıda önerildiği gibi ham utf-8) için çalıştı, ancak aynı cihazdan GoodReader için çalışmaz. Herhangi bir fikir?
Thilo

1
IE7 ve 8'in de apostrophs kaçması gerekir: .Replace ("'", Uri.HexEscape (' \ ''))
TomZ

1
Doğrudan UTF-8 karakterleri yazmak, Firefox, Chrome ve Opera'nın mevcut sürümleri için işe yarıyor gibi görünüyor. Safari ve IE test etmedi.
Martin Tournoij

20
Neden bunları birleştirmeyin Content-Disposition: attachment; filename*=UTF-8''Na%C3%AFve%20file.txt; filename=Na%C3%AFve%20file.txtve tarayıcı koklamasını atlamayın? Işe yarar mı?
Dave Van den Eynde

9
Fastmail'deki nazik insanlar başka bir geçici çözüm buldular: blog.fastmail.com/2011/06/24/download-non-english-filenames Content-Disposition: attachment; Dosya adı = "foo-% c3% a4.html"; dosyaadı * = UTF-8''foo-% c3% a4.html DosyaAdının iki kez belirtilmesi (UTF-8 öneki olmadan bir kez ve bir kez ile) IE8-11, Edge, Chrome, Firefox ve Safari'de ( elma sabit safari gibi görünüyor, bu yüzden şimdi orada da çalışıyor)
wullinkm

169

Basit ve çok sağlam bir alternatif var: İstediğiniz dosya adını içeren bir URL kullanın .

Son eğik çizgiden sonraki ad istediğiniz ad olduğunda, ek başlıklara ihtiyacınız yoktur!

Bu hile çalışıyor:

/real_script.php/fake_filename.doc

Sunucunuz URL yeniden yazmayı (örneğin mod_rewriteApache'de) destekliyorsa , komut dosyası parçasını tamamen gizleyebilirsiniz.

URL'lerdeki karakterler, bayt-byte bayt olarak kodlanmış UTF-8 biçiminde olmalıdır:

/mot%C3%B6rhead   # motörhead

3
GetAttachment.aspx / fake_filename.doc? İd = 34'ü (yalnızca Apache garipliği olmasına rağmen) deneyin
Kornel

2
bu harika bir çözüm; gerçekten çok yardımcı oldu. Teşekkürler.
kristopolous

6
Tavşan yolundan indim ve diğer çözümlerden bazılarını denedim; üstbilgileri doğru bir şekilde ayarlamak için doğru tarayıcıyı ve sürümü koklamaya çalışmak çok fazla bir kabus. Chrome, hiçbir şekilde aynı şekilde davranmayan Safari'yi yanlış bir şekilde tanımlıyordu (doğru kodlanmamışsa virgüllerde kesiliyor). Sorunu kendinize saklayın, bu çözümü kullanın ve URL'yi gerektiği gibi takma adı kullanın.
mpen

3
/:id/:filenameYöntem gerçekten basit ve eserleri, teşekkür ederim!
Luca Steeb

2
Bin kere "Evet". Bununla ciddi zaman kazanacaksınız. Daha eşit - bazı Android tarayıcıları göz ardı edecek Content-Dispositionve bunun yerine çok ilginç dosya adları oluşturacak (yolunuzdan oluşturulacaklar). Bu nedenle, akıl sağlığını korumak için tek çözüm Content-Disposition: attachment, istenen dosya
adını

73

RFC 6266 , “ Köprü Metni Aktarım Protokolü'nde (HTTP) İçerik-Bertaraf Üstbilgisi Alanının Kullanımı ” açıklanmaktadır . Bundan alıntı:

6. Uluslararasılaşma Konuları

filename*” Parametresi ( Bölüm 4.3 ), [ RFC5987 ] 'de tanımlanan kodlamayı kullanarak sunucunun ISO-8859-1 karakter kümesi dışındaki karakterleri iletmesine ve isteğe bağlı olarak kullanılan dili belirtmesine olanak tanır.

Ve örnekler bölümünde :

Bu örnek yukarıdakiyle aynıdır, ancak RFC 5987'yi uygulamayan kullanıcı aracılarıyla uyumluluk için "dosyaadı" parametresini ekler :

Content-Disposition: attachment;
                     filename="EURO rates";
                     filename*=utf-8''%e2%82%ac%20rates

Not: RFC 5987 kodlamasını desteklemeyen kullanıcı aracıları, “ filename*” sonrasında gerçekleştiğinde “ ” yoksayılır filename.

Gelen Ek D artış çalışabilirlik için önerilerden uzun bir liste de var. Ayrıca , uygulamaları karşılaştıran bir siteye işaret eder . Yaygın dosya adları için geçerli olan tüm geçiş testleri şunları içerir:

  • attwithisofnplain : kodlama olmadan çift tırnaklı düz ISO-8859-1 dosya adı. Bu, tümü ISO-8859-1 olan ve en azından onaltılık basamakların önünde olmayan yüzde işaretleri içermeyen bir dosya adı gerektirir.
  • attfnboth : yukarıda açıklanan sırayla iki parametre. IE8 “ filename” parametresini kullanmasına rağmen, çoğu tarayıcıdaki çoğu dosya adı için çalışmalıdır .

Bu RFC 5987 dönüş referanslarında RFC 2231 gerçek biçimini tarif eder. 2231 öncelikle posta içindir ve 5987 bize HTTP üstbilgileri için hangi bölümlerin kullanılabileceğini söyler. Bunu , RFC 2388 ( özellikle bölüm 4.4 ) ve HTML 5 taslağı tarafından yönetilen bir multipart/form-dataHTTP gövdesi içinde kullanılan MIME başlıklarıyla karıştırmayın .


1
Safari'de sorun yaşadım. Rusça isimleri olan dosyaları indirirken hatalı ve okunamayan karakterler aldı. Çözüm yardımcı oldu. Ancak tek bir satırda başlık göndermeliyiz (!!!).
evtuhovdo

16

Cevabında Jim tarafından belirtilen taslak RFC'den bağlantılı aşağıdaki belge , soruyu daha da ele alıyor ve kesinlikle doğrudan bir nota değer:

HTTP Content-Disposition başlığı ve RFC 2231/2047 Kodlaması için Test Durumları


Dosya adı parametresini kodlamanın her iki yolunu da sağlayabildiğini ve eski tarayıcılar ve yeni tarayıcılarla (bu durumda eski MSIE8 ve Safari) düzgün çalıştıklarını unutmayın. Kontrol attfnboth @AtifAziz bahsettiği raporda.
Pablo Montilla

11

asp.net mvc2'de böyle bir şey kullanıyorum:

return File(
    tempFile
    , "application/octet-stream"
    , HttpUtility.UrlPathEncode(fileName)
    );

Eğer mvc (2) kullanmıyorsanız sadece dosya adını kullanarak kodlayabilirsiniz

HttpUtility.UrlPathEncode(fileName)

2
Dosya adı kodlaması için URL kodlaması geçerli değil, tarayıcılar URL'lerin kodunu çözmemelidir.
SerialSeb

IE 11 kesinlikle bu alandaki url kodlamasını çözmez.
sözde

Ancak tarayıcı Chrome veya IE olduğunda UrlEncoded olması gerekiyor, FF, Safari ve Opera gibi diğerleri kodlama olmadan iyi çalışıyor
Reza

11

Dosya adını çift tırnak içine alın. Sorunu benim için çözdü. Bunun gibi:

Content-Disposition: attachment; filename="My Report.doc"

http://kb.mozillazine.org/Filenames_with_spaces_are_truncated_upon_download

Birden fazla seçeneği test ettim. Tarayıcılar özellikleri desteklemiyor ve farklı davranıyor, çift tırnakların en iyi seçenek olduğuna inanıyorum.


3
Bu ne yazık ki yukarıdaki cevaplarda açıklanan tüm sorunları çözmez.
Luca Steeb

2
Bu boşluklu, bir dosya adı dönmek sağlayacak &, %, #o çözer Yani vb.
Don Cheadle

Dosya adı çift tırnak içeriyorsa (evet bu olabilir), RFC 6266'da belirtildiği gibi, dosya adı bir "alıntı-dize" dir ve alıntılanan bir dize içindeki RFC 2616 çift tırnaklarında belirtildiği gibi bir ters eğik çizgiyle kaçılmalıdır.
Christophe Roussy

10

Ben kodlama için aşağıdaki kod parçacıkları kullanın ( fileName dosya adı ve uzantısı, yani: test.txt içerir varsayalım):


PHP:

if ( strpos ( $_SERVER [ 'HTTP_USER_AGENT' ], "MSIE" ) > 0 )
{
     header ( 'Content-Disposition: attachment; filename="' . rawurlencode ( $fileName ) . '"' );
}
else
{
     header( 'Content-Disposition: attachment; filename*=UTF-8\'\'' . rawurlencode ( $fileName ) );
}

Java:

fileName = request.getHeader ( "user-agent" ).contains ( "MSIE" ) ? URLEncoder.encode ( fileName, "utf-8") : MimeUtility.encodeWord ( fileName );
response.setHeader ( "Content-disposition", "attachment; filename=\"" + fileName + "\"");

Doğru, RFC 6266-> RFC 5987'de kullanıldığı rawurlencodeiçin en azından filename*=düzenleme başlığı için PHP'de olmalıdır (bkz. Tools.ietf.org/html/rfc6266#section-4.1 & tools.ietf.org/html/rfc5987#section -3.2.1 ) yüzde kaçmadan boşluğa izin vermiyor ( öte yandan, burada sadece ASCII bulunmalı olsa da, kaçmadan bir boşluğa izin verebileceği görülüyor). Rawurlencode'un tam katılığıyla kodlamak gerekli değildir, bu nedenle birkaç karakter kaçınılmazdır : gist.github.com/brettz9/8752120value-charsext-valuefilename=
Brett Zamir

9

ASP.NET Web API, ben dosya adı url kodlamak:

public static class HttpRequestMessageExtensions
{
    public static HttpResponseMessage CreateFileResponse(this HttpRequestMessage request, byte[] data, string filename, string mediaType)
    {
        HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
        var stream = new MemoryStream(data);
        stream.Position = 0;

        response.Content = new StreamContent(stream);

        response.Content.Headers.ContentType = 
            new MediaTypeHeaderValue(mediaType);

        // URL-Encode filename
        // Fixes behavior in IE, that filenames with non US-ASCII characters
        // stay correct (not "_utf-8_.......=_=").
        var encodedFilename = HttpUtility.UrlEncode(filename, Encoding.UTF8);

        response.Content.Headers.ContentDisposition =
            new ContentDispositionHeaderValue("attachment") { FileName = encodedFilename };
        return response;
    }
}

IE 9 Düzeltilmedi
IE 9 Sabit


5

Eski Kaşifler dahil olmak üzere tüm büyük tarayıcılarda aşağıdaki kodu test ettim (uyumluluk modu aracılığıyla) ve her yerde iyi çalışır:

$filename = $_GET['file']; //this string from $_GET is already decoded
if (strstr($_SERVER['HTTP_USER_AGENT'],"MSIE"))
  $filename = rawurlencode($filename);
header('Content-Disposition: attachment; filename="'.$filename.'"');

5

"Download.php" betiğimde şu kodla karşılaştım ( bu blog yazısı ve bu test senaryolarına dayanarak ).

$il1_filename = utf8_decode($filename);
$to_underscore = "\"\\#*;:|<>/?";
$safe_filename = strtr($il1_filename, $to_underscore, str_repeat("_", strlen($to_underscore)));

header("Content-Disposition: attachment; filename=\"$safe_filename\""
.( $safe_filename === $filename ? "" : "; filename*=UTF-8''".rawurlencode($filename) ));

Yalnızca iso-latin1 ve "güvenli" karakterler kullanıldığı sürece standart dosya adı = "..." yöntemini kullanır; değilse, dosya adını * = UTF-8 '' url kodlu şekilde ekler. Göre bu özel test durumu , bu MSIE9 dan çalışmalıdır yukarı ve son FF üzerinde, Chrome, Safari; alt MSIE sürümünde, dosya adının ISO8859-1 sürümünü içeren dosya adı sunmalı ve bu kodlamada olmayan karakterlerin alt çizgilerini içermelidir.

Son not: maks. her başlık alanı için boyut apache'de 8190 bayttır. UTF-8 karakter başına dört bayta kadar olabilir; rawurlencode sonra bir karakter başına x3 = 12 bayt. Oldukça verimsiz olmakla birlikte, dosya adında 600'den fazla "gülümsemenin"% F0% 9F% 98% 81 olması hala teorik olarak mümkün olmalıdır.


... ancak aktarılabilir maksimum dosya adı uzunluğu da istemciye bağlıdır. Az önce [89 gülümsüyor] .pdf dosya adının MSIE11 üzerinden geldiğini öğrendim. Firefox37'de en fazla [111x 😁] .pdf'dir. Chrome41, 110. gülümseme ile dosya adını kesiyor. İlginç bir şekilde, son ek tamam aktarılır.
apurkrt

5

Eğer bir nodejs arka ucu kullanıyorsanız, burada bulduğum aşağıdaki kodu kullanabilirsiniz

var fileName = 'my file(2).txt';
var header = "Content-Disposition: attachment; filename*=UTF-8''" 
             + encodeRFC5987ValueChars(fileName);

function encodeRFC5987ValueChars (str) {
    return encodeURIComponent(str).
        // Note that although RFC3986 reserves "!", RFC5987 does not,
        // so we do not need to escape it
        replace(/['()]/g, escape). // i.e., %27 %28 %29
        replace(/\*/g, '%2A').
            // The following are not required for percent-encoding per RFC5987, 
            // so we can allow for a little better readability over the wire: |`^
            replace(/%(?:7C|60|5E)/g, unescape);
}

1
Kullanmak daha iyi encodeURI(str). Dosya adındaki tarihlerle örnek olarak: encodeURIComponent('"Kornél Kovács 1/1/2016')=> "Kornél Kovács 1% 2F1% 2F2016" vs. encodeURI('"Kornél Kovács 1/1/2016')=> "Kornél Kovács 1/1/2016"
gdibble

4

PHP'de bu benim için yaptı (dosya adının UTF8 kodlu olduğu varsayılarak):

header('Content-Disposition: attachment;'
    . 'filename="' . addslashes(utf8_decode($filename)) . '";'
    . 'filename*=utf-8\'\'' . rawurlencode($filename));

IE8-11, Firefox ve Chrome'a ​​karşı test edilmiştir.
Tarayıcı dosya adını * = utf-8 yorumlayabilirse, dosya adının UTF8 sürümünü kullanır, aksi takdirde kodu çözülmüş dosya adını kullanır. Dosya adınız ISO-8859-1'de temsil edilemeyen karakterler içeriyorsa, iconvbunun yerine kullanmayı düşünebilirsiniz .


3
Bu kod soruyu cevaplayabilse de, soruyu neden ve / veya nasıl cevapladığı konusunda ek bağlam sağlamak uzun vadeli değerini önemli ölçüde artıracaktır. Lütfen biraz açıklama eklemek için cevabınızı düzenleyin .
Toby Speight

2
Vay, yukarıdaki kod sadece cevapların hiçbiri bu şekilde değerlendirilmedi veya eleştirilmedi. Ayrıca neden zaten yeterince iyi cevaplandı bulundu : IE dosya adını yorumlamıyor * = utf-8 ama bu komut dosyasının sunduğu dosya adının ISO8859-1 sürümüne ihtiyacı var. Sadece tembel PHP için basit bir kod vermek istedim.
Gustav

Sorunun dile özgü olmadığı, ancak başlık kodlamasını uygularken hangi RFC'lere bağlı kalacağına göre bunun indirilmesi gerektiğini düşünüyorum. Ancak, bu cevap için teşekkürler, PHP için, bu kod benim sıkıntıları giderdi.
j4k3

Teşekkür ederim. Bu cevap soruyu kesinlikle cevaplamamış olabilir, ancak tam olarak aradığım şeydi ve Python'daki sorunu çözmeme yardımcı oldu.
Lyndsy Simon

1
Kullanıcı dosyanın adını kontrol edebilir, bu kod bir saldırı vektörü olarak kullanılabilir eminim.
Antti Haapala

3

Bir müşteri sorununa yanıt olarak bugün tüm bunları denediğimden beri sadece bir güncelleme

  • Japonca için yapılandırılmış Safari hariç, test edilen tüm tarayıcılar en iyi filename = text.pdf ile çalıştı; burada metin, url kodlaması olmadan utf-8'de ASP.Net/IIS tarafından serileştirilmiş bir müşteri değeridir. Herhangi bir nedenle, İngilizce için yapılandırılmış Safari, utf-8 Japonca adıyla bir dosyayı kabul eder ve düzgün bir şekilde kaydeder, ancak Japonca için yapılandırılan aynı tarayıcı, utf-8 karakterleri yorumlanmamış olarak kaydeder. Test edilen diğer tüm tarayıcılar, url kodlaması olmadan kodlanmış utf-8 dosya adıyla en iyi / iyi (dil yapılandırmasına bakılmaksızın) çalışıyor gibi görünüyordu.
  • Ben Rfc5987 / 8187'e uygulayan tek tarayıcı bulamadık hiç . En yeni Chrome, Firefox derlemeleri artı IE 11 ve Edge ile test ettim. Üstbilgiyi yalnızca dosya adıyla ayarlamayı denedim * = utf-8''texturlencoded.pdf, hem dosyaadı = text.pdf; Dosya adı * = utf-8''texturlencoded.pdf. Rfc5987 / 8187'nin hiçbir özelliğinin yukarıdakilerin hiçbirinde doğru bir şekilde işlenmediği görülmüştür.

Bu iyi bir güncelleme. Denediğiniz spesifik testleri ayrıntılı olarak açıklayabilir misiniz?
Brad

3

PHP çerçeve Symfony'nin 4 sahiptir $filenameFallbackiçinde HeaderUtils::makeDisposition. Ayrıntılar için bu işleve bakabilirsiniz - yukarıdaki cevaplara benzer.

Kullanım örneği:

$filenameFallback = preg_replace('#^.*\.#', md5($filename) . '.', $filename);
$disposition = $response->headers->makeDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $filename, $filenameFallback);
$response->headers->set('Content-Disposition', $disposition);

1

Klasik ASP Çözümü

Modern tarayıcıların çoğu geçen destekleyen Filenameolarak UTF-8şimdi ama dayanıyordu bir Dosya Yükleme çözüm I kullanımı ile olduğu gibi FreeASPUpload.Net (site artık üzere, bağlantı noktaları var archive.org ) ayrıştırma gibi olmaz işi İkili ASCII desteklemeyen karakterlere ulaşıncaya kadar UTF-8 kodlu verileri geçtiğinizde iyi çalışan tek baytlı ASCII kodlu dizeleri okumaya dayanıyordu.

Ancak UTF-8 olarak ikili okuma ve ayrıştırma kodu almak için bir çözüm bulmak mümkün.

Public Function BytesToString(bytes)    'UTF-8..
  Dim bslen
  Dim i, k , N 
  Dim b , count 
  Dim str

  bslen = LenB(bytes)
  str=""

  i = 0
  Do While i < bslen
    b = AscB(MidB(bytes,i+1,1))

    If (b And &HFC) = &HFC Then
      count = 6
      N = b And &H1
    ElseIf (b And &HF8) = &HF8 Then
      count = 5
      N = b And &H3
    ElseIf (b And &HF0) = &HF0 Then
      count = 4
      N = b And &H7
    ElseIf (b And &HE0) = &HE0 Then
      count = 3
      N = b And &HF
    ElseIf (b And &HC0) = &HC0 Then
      count = 2
      N = b And &H1F
    Else
      count = 1
      str = str & Chr(b)
    End If

    If i + count - 1 > bslen Then
      str = str&"?"
      Exit Do
    End If

    If count>1 then
      For k = 1 To count - 1
        b = AscB(MidB(bytes,i+k+1,1))
        N = N * &H40 + (b And &H3F)
      Next
      str = str & ChrW(N)
    End If
    i = i + count
  Loop

  BytesToString = str
End Function

Kredi gider Saf ASP Dosya yükle uygulayarak BytesToString()gelen işlevi include_aspuploader.aspkendi kodunda Elde edebildi UTF-8çalışma dosya.


kullanışlı bağlantılar


-1

Bir web uygulamasında benzer bir sorun yaşadık ve HTML'den dosya adını okuyarak <input type="file">ve bunu url ile kodlanmış formda yeni bir HTML'de ayarlayarak sonuçlandırdık <input type="hidden">. Tabii ki bazı tarayıcılar tarafından döndürülen "C: \ fakepath \" yolunu kaldırmamız gerekiyordu.

Tabii ki bu OP'nin sorusuna doğrudan cevap vermiyor, ancak başkaları için bir çözüm olabilir.


1
Tamamen farklı bir konu. Soru indirme ile ilgili , cevabınız yükleme ile ilgili .
Oskar Berggren

-3

Normalde dosya adlarını URL kodluyorum (% xx ile) ve tüm tarayıcılarda çalışıyor gibi görünüyor. Yine de bazı testler yapmak isteyebilirsiniz.


10
Birkaç test yaptım ve tüm tarayıcılarda bu şekilde çalışmaz, bu yüzden soru. :)
Atif Aziz
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.