HTTP में कंटेंट-डिस्पोजल हेडर के फ़ाइलनाम पैरामीटर को कैसे एनकोड करना है?


533

वेब ब्राउज़र जो वेब ब्राउज़र में सीधे रेंडर किए जाने के बजाय किसी संसाधन को डाउनलोड करने के लिए मजबूर करना चाहते हैं , फॉर्म की HTTP प्रतिक्रिया में हेडर जारी करते हैं:Content-Disposition

Content-Disposition: attachment; filename=FILENAME

filenameपैरामीटर जिसमें संसाधन ब्राउज़र द्वारा डाउनलोड किया जाता है फ़ाइल का नाम सुझाने के लिए इस्तेमाल किया जा सकता। RFC 2183 (सामग्री-विवाद), हालांकि, खंड 2.3 (फ़ाइल नाम पैरामीटर) में कहा गया है कि फ़ाइल नाम केवल US-ASCII वर्णों का उपयोग कर सकता है:

वर्तमान [RFC 2045] व्याकरण पैरामीटर मान (और इसलिए सामग्री-विवाद फ़ाइल नाम) को US-ASCII तक सीमित करता है। हम फ़ाइल नाम में मनमाने चरित्र सेट की अनुमति देने की महान वांछनीयता को पहचानते हैं, लेकिन यह आवश्यक तंत्र को परिभाषित करने के लिए इस दस्तावेज़ के दायरे से परे है।

अनुभवजन्य साक्ष्य है, फिर भी, सबसे लोकप्रिय वेब ब्राउज़र आज गैर-यूएस-एएससीआईआई पात्रों को अनुमति देने के लिए प्रतीत होते हैं (मानक के अभाव के लिए) एन्कोडिंग योजना और फ़ाइल नाम के चरित्र सेट विनिर्देश पर असहमत हैं। प्रश्न तो यह है कि लोकप्रिय ब्राउज़रों द्वारा नियोजित विभिन्न योजनाएं और एन्कोडिंग क्या हैं यदि फ़ाइल का नाम "navevefile" (उद्धरण के बिना और जहां तीसरा अक्षर U + 00EF है) को सामग्री-विवाद शीर्षक में एन्कोड किया जाना चाहिए?

इस प्रश्न के उद्देश्य के लिए, लोकप्रिय ब्राउज़र :

  • फ़ायरफ़ॉक्स
  • इंटरनेट एक्स्प्लोरर
  • सफारी
  • गूगल क्रोम
  • ओपेरा

समझ गया कि यह मोबाइल सफारी के लिए काम कर रहा है (कच्चे यूटी -8 जैसा कि @ मर्टिन dingrding-Thomsen द्वारा सुझाया गया है), लेकिन यह उसी डिवाइस से GoodReader के लिए काम नहीं करता है। कोई विचार?
थिलो


1
कोर्नेल का उत्तर कम से कम प्रतिरोध का मार्ग साबित हुआ, यदि आप पथ के अंतिम खंड को निर्धारित कर सकते हैं; इसके साथ युगल Content-Disposition: attachment
अंती हापाला

जवाबों:


94

इस बात की चर्चा है, प्रस्तावित आरएफसी 5987 में , "हाइपरटेक्स्ट ट्रांसफर प्रोटोकॉल (HTTP) हैडर फील्ड पैरामीटर्स के लिए कैरेक्टर सेट और लैंग्वेज एन्कोडिंग", ब्राउज़र टेस्टिंग और बैकवर्ड संगतता के लिंक सहित ।

RFC 2183 इंगित करता है कि इस तरह के हेडर को RFC 2184 के अनुसार एनकोड किया जाना चाहिए , जिसे RFC 2231 द्वारा पालन किया गया था , ऊपर RFC के मसौदे द्वारा कवर किया गया था।


5
यह भी ध्यान दें कि इंटरनेट ड्राफ्ट ("ड्राफ्ट RFC" नहीं) समाप्त हो गया है, और अंतिम दस्तावेज RFC 5987 ( greenbytes.de/tech/webdav/rfc5987.html )
जूलियन

11
इस से संबंधित, मैंने पाया कि फ़ायरफ़ॉक्स (संस्करण 4-9 समावेशी) टूट जाता है अगर फ़ाइल नाम में एक अल्पविराम (,) है, उदाहरण के लिए Content-Disposition: filename="foo, bar.pdf"। परिणाम यह है कि फ़ायरफ़ॉक्स फ़ाइल को सही ढंग से डाउनलोड करता है लेकिन .partविस्तार (जैसे foo,bar.pdf-1.part) रखता है । फिर, निश्चित रूप से फ़ाइल सही ढंग से नहीं खुलेगी क्योंकि एप्लिकेशन से संबद्ध नहीं है .part। अन्य ASCII वर्ण ठीक काम करने लगते हैं।
कैचडेव

3
IE व्यवहार के बारे में अधिक जानकारी के लिए, blogs.msdn.com/b/ieinternals/archive/2010/06/07/…
EricLaw

5
@ कैचडेव: आप "अनुलग्नक" भूल गए? अंश।
क्रिस्टोफर हैमरस्ट्रॉम

6
सभी सब में, यह 74 अपवोट्स के साथ लिंक-ओनली उत्तर के अलावा कुछ भी नहीं है।
अंती हापाला

364

मुझे पता है कि यह एक पुरानी पोस्ट है लेकिन यह अभी भी बहुत प्रासंगिक है। मैंने पाया है कि आधुनिक ब्राउज़र rfc5987 का समर्थन करते हैं, जो utf-8 एन्कोडिंग, प्रतिशत एन्कोडेड (url- एन्कोडेड) की अनुमति देता है। फिर Na Thenve file.txt बन जाता है:

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

सफारी (5) इसका समर्थन नहीं करती है। इसके बजाय आपको फ़ाइल का नाम सीधे अपने utf-8 एन्कोडेड हेडर में लिखने के सफारी मानक का उपयोग करना चाहिए:

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

IE8 और पुराने इसे या तो समर्थन नहीं करते हैं और आपको utf-8 एन्कोडिंग के IE मानक का उपयोग करने की आवश्यकता है, प्रतिशत एन्कोडेड:

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

ASP.Net में मैं निम्नलिखित कोड का उपयोग करता हूं:

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

मैंने IE7, IE8, IE9, Chrome 13, Opera 11, FF5, Safari 5 का उपयोग करके उपरोक्त परीक्षण किया।

अद्यतन नवंबर 2013:

यहां वह कोड है जो मैं वर्तमान में उपयोग करता हूं। मुझे अभी भी IE8 का समर्थन करना है, इसलिए मैं पहले भाग से छुटकारा नहीं पा सकता हूं। यह पता चलता है कि एंड्रॉइड पर ब्राउज़र अंतर्निहित एंड्रॉइड डाउनलोड प्रबंधक का उपयोग करते हैं और यह मानक तरीके से फ़ाइल नामों को पार्स नहीं कर सकता है।

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

उपरोक्त अब IE7-11, Chrome 32, Opera 12, FF25, Safari 6 में परीक्षण किया गया, डाउनलोड के लिए इस फ़ाइलनाम का उपयोग करते हुए: download abcABCæøåÆØÅäöüïëêîâéíáóýñ½§! # ¤% & () = `@ £ $ € {[]} + ´¨ ^ ~ '-_,;। txt

IE7 पर यह कुछ पात्रों के लिए काम करता है लेकिन सभी के लिए नहीं। लेकिन आजकल IE7 की परवाह किसे है?

यह वह फ़ंक्शन है जिसका उपयोग मैं एंड्रॉइड के लिए सुरक्षित फ़ाइल नाम उत्पन्न करने के लिए करता हूं। ध्यान दें कि मुझे नहीं पता कि कौन से वर्ण Android पर समर्थित हैं, लेकिन मैंने परीक्षण किया है कि ये सुनिश्चित करने के लिए काम करते हैं:

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

@ टॉम: मैंने IE7 और IE8 में परीक्षण किया और यह पता चला कि मुझे एपोस्ट्रोफ (') से बचने की आवश्यकता नहीं है। क्या आपके पास एक उदाहरण है जहां यह विफल रहता है?

@ डेव वान डेन आईंडे: आरएफसी 6266 एंड्रॉइड और IE7 + 8 को छोड़कर काम करता है और एक लाइन पर दो फ़ाइल नामों को मिलाकर मैंने इसे प्रतिबिंबित करने के लिए कोड अपडेट किया है। सुझाव के लिए धन्यवाद।

@ थिलो: गुडरीडर या किसी अन्य गैर-ब्राउज़र के बारे में कोई विचार नहीं है। एंड्रॉइड दृष्टिकोण का उपयोग करके आपके पास कुछ भाग्य हो सकते हैं।

@ एलेक्स ज़ुकोव्स्की: मुझे नहीं पता कि क्यों लेकिन कनेक्ट पर चर्चा के रूप में यह बहुत अच्छी तरह से काम नहीं करता है।


1
समझे कि यह मोबाइल सफारी के लिए काम कर रहा है (जैसा कि ऊपर बताया गया है, कच्चे रॉफ़ -8), लेकिन यह उसी डिवाइस से गुडरीडर के लिए काम नहीं करता है। कोई विचार?
थिलो

1
IE7 और 8 को भी अपोस्ट्रोफ़्स से बचना चाहिए: .Replace ("'", Uri.HexEscape (' \ ''))
TomZ

1
सीधे तौर पर UTF-8 अक्षर लिखना फ़ायरफ़ॉक्स, क्रोम और ओपेरा के वर्तमान संस्करणों के लिए काम करता है। सफारी और IE का परीक्षण नहीं किया।
मार्टिन टूरनोइज

20
क्यों नहीं, उन्हें संयोजन के रूप में Content-Disposition: attachment; filename*=UTF-8''Na%C3%AFve%20file.txt; filename=Na%C3%AFve%20file.txtऔर सूँघने वाले ब्राउज़र को छोड़ दें? क्या इससे काम हो जायेगा?
डेव वान डेन आईंडी

9
फास्टमेल में दयालु लोगों को एक और वर्कअराउंड मिला: blog.fastmail.com/2011/06/24/download-non-english-filenames सामग्री- विवाद : लगाव; फ़ाइल नाम = "foo-% C3% a4.html"; फ़ाइल नाम * = UTF-8''foo-% c3% a4.html फ़ाइल का नाम निर्दिष्ट करना दो बार (UTF-8 उपसर्ग के बिना एक समय और एक बार) इसे IE8-11, एज, क्रोम, फ़ायरफ़ॉक्स और सफारी में काम करता है ( लगता है जैसे सेब की
तय्यारी है

169

एक सरल और बहुत मजबूत विकल्प है: एक URL का उपयोग करें जिसमें वह फ़ाइल नाम शामिल है जिसे आप चाहते हैं

जब अंतिम स्लैश के बाद नाम आप चाहते हैं, तो आपको किसी अतिरिक्त हेडर की आवश्यकता नहीं है!

यह चाल काम करती है:

/real_script.php/fake_filename.doc

और यदि आपका सर्वर URL पुनर्लेखन (उदाहरण mod_rewriteके लिए अपाचे) में समर्थन करता है तो आप स्क्रिप्ट भाग को पूरी तरह से छिपा सकते हैं।

URLs में वर्ण UTF-8, urlencoded byte-by-byte में होने चाहिए:

/mot%C3%B6rhead   # motörhead

3
GetAttachment.aspx / fake_filename.doc? Id = 34 आज़माएं (हालांकि यह अपाचे-केवल क्विक हो सकता है)
कोर्नेल

2
यह एक शानदार समाधान है; वास्तव में मेरी बहुत मदद की। धन्यवाद।
क्रिस्टोपोलस

6
मैं खरगोश के निशान के नीचे गया और कुछ अन्य समाधानों की कोशिश की; हेडर को सही ढंग से सेट करने के लिए सही ब्राउज़र और संस्करण को सूँघने की कोशिश करना बहुत बुरा सपना है। क्रोम गलत तरीके से सफारी के रूप में पहचान कर रहा था जो समान व्यवहार नहीं करता है (कॉमा पर टूटता है यदि सही तरीके से एन्कोड नहीं किया गया है)। अपने आप को परेशानी से बचाएं, इस समाधान का उपयोग करें और आवश्यकतानुसार URL को उपनाम दें।
एमपीएन

3
/:id/:filenameविधि वास्तव में सरल है और काम करता है, धन्यवाद!
लुका स्टेब

2
एक हज़ार बार "हाँ"। आप गंभीरता से इसके साथ समय जीतेंगे। और भी - कुछ एंड्रॉइड ब्राउज़र इसकी अनदेखी करेंगे Content-Dispositionऔर इसके बजाय बहुत दिलचस्प फ़ाइलनाम बनाएंगे (वे आपके पथ से उत्पन्न होंगे)। इसलिए किसी की पवित्रता को बनाए रखने का एकमात्र उपाय Content-Disposition: attachmentअंतिम पथ घटक के रूप में वांछित फ़ाइलनाम को सेट करना और पारित करना है:
जूलिक

73

RFC 6266 " हाइपरटेक्स्ट ट्रांसफर प्रोटोकॉल (HTTP) में कंटेंट-डिस्पोजल हैडर फील्ड का उपयोग " का वर्णन करता है । उस से उद्धरण:

6. अंतर्राष्ट्रीयकरण संबंधी विचार

" filename*" पैरामीटर ( धारा 4.3 ), एन्कोडिंग [में परिभाषित का उपयोग कर RFC5987 ], ISO-8859-1 वर्ण सेट के बाहर संचारित पात्रों के लिए सर्वर की अनुमति देता है, और भी वैकल्पिक करने के लिए उपयोग में भाषा निर्दिष्ट करें।

और उनके उदाहरण अनुभाग में :

यह उदाहरण ऊपर वाले के समान है, लेकिन RFC 5987 को लागू नहीं करने वाले उपयोगकर्ता एजेंटों के साथ संगतता के लिए "फ़ाइल नाम" पैरामीटर को जोड़ना :

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

नोट: वे उपयोगकर्ता एजेंट जो RFC 5987 एन्कोडिंग का समर्थन नहीं करते हैं " filename*" के बाद होने पर " filename" को अनदेखा करते हैं ।

में परिशिष्ट डी वहाँ भी वृद्धि अंतर करने के लिए सुझावों की एक लंबी सूची है। यह एक साइट पर भी इंगित करता है जो कार्यान्वयन की तुलना करता है । सामान्य फ़ाइल नामों के लिए उपयुक्त वर्तमान सभी-पास परीक्षण में शामिल हैं:

  • Attwithisofnplain : सादा ISO-8859-1 फ़ाइल नाम दोहरे कोट्स के साथ और एन्कोडिंग के बिना। इसके लिए एक फ़ाइल नाम की आवश्यकता होती है जो सभी ISO-8859-1 है और इसमें प्रतिशत चिह्न नहीं हैं, कम से कम हेक्स अंकों के सामने नहीं है।
  • attfnboth : ऊपर वर्णित क्रम में दो पैरामीटर। अधिकांश ब्राउज़र पर फ़ाइल नाम के लिए काम करना चाहिए, हालांकि IE8 " filename" पैरामीटर का उपयोग करेगा ।

यह RFC 5987 बदले RFC 2231 का संदर्भ देता है , जो वास्तविक प्रारूप का वर्णन करता है। 2231 मुख्य रूप से मेल के लिए है, और 5987 हमें बताता है कि HTTP हेडर के लिए भी क्या भागों का उपयोग किया जा सकता है। एक multipart/form-dataHTTP निकाय के अंदर उपयोग किए जाने वाले MIME हेडर के साथ इसे भ्रमित न करें , जो RFC 2388 ( विशेष रूप से खंड 4.4 ) और HTML 5 ड्राफ्ट द्वारा शासित है ।


1
मुझे सफारी में परेशानी हुई। रूसी नामों वाली फ़ाइलों को डाउनलोड करते समय गलत और अपठनीय अक्षर प्राप्त हुए। समाधान से मदद मिली है। लेकिन हमें एक ही पंक्ति (!!!) में हेडर भेजने की आवश्यकता है।
evtuhovdo

16

जिम द्वारा उल्लेखित RFC के मसौदे से जुड़े निम्नलिखित दस्तावेज उनके जवाब में सवाल का जवाब देते हैं और निश्चित रूप से यहां एक प्रत्यक्ष नोट के लायक है:

HTTP कंटेंट-डिस्पोजल हेडर और RFC 2231/2047 एनकोडिंग के लिए टेस्ट केस


ध्यान दें कि फ़ाइल नाम पैरामीटर को एन्कोडिंग के दोनों तरीकों की आपूर्ति कर सकता है, और वे पुराने ब्राउज़रों और नए ब्राउज़रों (इस मामले में पुराने MSIE8 और सफारी) के साथ सही ढंग से काम करते दिखाई देते हैं। @AtifAziz द्वारा उल्लिखित रिपोर्ट में attfnboth की जाँच करें ।
पाब्लो मॉन्टिला

11

asp.net mvc2 में मैं कुछ इस तरह का उपयोग करें:

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

मुझे लगता है कि अगर आप mvc (2) का उपयोग नहीं करते हैं तो आप केवल फ़ाइल नाम का उपयोग कर सांकेतिक शब्दों में बदलना कर सकते हैं

HttpUtility.UrlPathEncode(fileName)

2
फ़ाइल नाम एन्कोडिंग के लिए Url एन्कोडिंग मान्य नहीं है, ब्राउज़र को url को डीकोड नहीं करना चाहिए।
सीरियलबेल

IE 11 निश्चित रूप से इस क्षेत्र में url एन्कोडिंग को डिकोड नहीं करता है।
छद्मकोडर

लेकिन यह ब्राउज़र या क्रोम या IE होने पर UrlEncoded होने की आवश्यकता होती है, जैसे एफएफ, सफारी और ओपेरा जैसे अन्य एन्कोडिंग के साथ ठीक काम करते हैं
रेजा

10

मैं एन्कोड करने के लिए निम्नलिखित कोड स्निपेट का उपयोग (यह मानते हुए fileName : test.txt फ़ाइल नाम और फ़ाइल का विस्तार, यानी शामिल हैं):


पीएचपी:

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

जावा:

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

सही, यह RFC 6266-> RFC 5987 (देखें tools.ietf.org/html/rfc6266#section-4.1) और tools.ietf.org/html/rfc5987#section में उपयोग किए जाने के बाद से rawurlencodePHP में कम से कम डिस्पेंस filename*=हेडर के लिए होना चाहिए । -3.2.1 ) प्रतिशत से बचने के बिना स्थान की अनुमति नहीं देता है ( दूसरी ओर, ऐसा लगता है कि यह बिना किसी स्थान पर भागने के लिए अनुमति दे सकता है, हालांकि केवल ASCII यहां मौजूद होना चाहिए)। यह पूरी तरह से कड़ाई से कच्ची कड़ेपन के साथ सांकेतिक शब्दों में बदलना आवश्यक नहीं है, इसलिए कुछ वर्णों को हटाया जा सकता है: gist.github.com/brettz9/8752120value-charsext-valuefilename=
ब्रेट ज़मीर

10

फ़ाइल का नाम डबल कोट्स में रखें। मेरे लिए समस्या का समाधान किया। ऐशे ही:

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

http://kb.mozillazine.org/Filenames_with_spaces_are_truncated_upon_download

मैंने कई विकल्पों का परीक्षण किया है। ब्राउज़र चश्मा का समर्थन नहीं करते हैं और अलग तरह से कार्य करते हैं, मेरा मानना ​​है कि दोहरे उद्धरण सबसे अच्छा विकल्प है।


3
यह दुख की बात है कि ऊपर दिए गए उत्तरों में बताई गई सभी समस्याओं का समाधान नहीं है।
लुका स्टीब

2
यह आपको, रिक्त स्थान के साथ एक फ़ाइल नाम वापस जाने के लिए अनुमति देगा &, %, #आदि तो यह है कि हल करती है।
डॉन चेडल

क्या होगा यदि फ़ाइल नाम में दोहरे उद्धरण शामिल हैं (हाँ यह हो सकता है), जैसा कि RFC 6266 में निर्दिष्ट है, फ़ाइल नाम एक "उद्धृत-स्ट्रिंग" है, और जैसा कि RFC 2616 में एक उद्धृत-स्ट्रिंग के भीतर डबल उद्धरण एक बैकस्लैश के साथ बच जाना चाहिए।
क्रिस्टोफ रूसो

9

ASP.NET वेब एपीआई में, मैं फ़ाइल नाम एनकोड करता हूं:

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 तय नहीं
IE 9 फिक्स्ड


5

मैंने सभी प्रमुख ब्राउज़रों में निम्नलिखित कोड का परीक्षण किया, जिसमें पुराने खोजकर्ता (संगतता मोड के माध्यम से) शामिल हैं, और यह हर जगह अच्छी तरह से काम करता है:

$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" स्क्रिप्ट ( इस ब्लॉगपोस्ट और इन परीक्षण मामलों के आधार पर ) में निम्नलिखित कोड के साथ समाप्त किया ।

$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) ));

यह फ़ाइल नाम = "..." के मानक तरीके का उपयोग करता है जब तक कि केवल आइसो-लैटिन 1 और "सुरक्षित" वर्ण उपयोग किए जाते हैं; यदि नहीं, तो यह फ़ाइल नाम * = UTF-8 '' url-encoded तरीका जोड़ता है। इस विशिष्ट परीक्षण मामले के अनुसार , इसे MSIE9 अप और हाल ही में FF, क्रोम, सफारी पर काम करना चाहिए; कम MSIE संस्करण पर, इसे फ़ाइल नाम का ISO8859-1 संस्करण प्रस्तुत करना चाहिए, इस एन्कोडिंग में वर्णों पर अंडरस्कोर नहीं है।

अंतिम नोट: अधिकतम। प्रत्येक हेडर फ़ील्ड के लिए आकार अपाचे पर 8190 बाइट्स है। UTF-8 प्रति चरित्र चार बाइट्स तक हो सकता है; rawurlencode के बाद, यह x3 = 12 बाइट्स प्रति एक वर्ण है। सुंदर अकुशल, लेकिन यह अभी भी सैद्धांतिक रूप से फ़ाइल नाम में 600 से अधिक "मुस्कुराहट"% F0% 9F% 98% 81 होना चाहिए।


... लेकिन अधिकतम ट्रांसफ़रेबल फ़ाइल नाम की लंबाई भी ग्राहक पर निर्भर करती है। बस पता चला है कि [89 smiles sm] .pdf फ़ाइल नाम MSIE11 के माध्यम से मिलता है। Firefox37 में, यह ज्यादातर [111x।] .Pdf पर है। Chrome41 ने 110 वीं मुस्कान में फ़ाइल नाम को काट दिया। दिलचस्प है, प्रत्यय ठीक स्थानांतरित किया गया है।
अपर्चर

5

यदि आप एक नोडज बैकएंड का उपयोग कर रहे हैं, तो आप निम्नलिखित कोड का उपयोग कर सकते हैं जो मैंने यहां पाया है

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
उपयोग करने के लिए बेहतर है encodeURI(str)। उदाहरण के लिए फ़ाइल नाम में तारीखों के साथ: encodeURIComponent('"Kornél Kovács 1/1/2016')=> "कोर्नेल कोवक्स 1% 2F1% 2F2016" बनाम encodeURI('"Kornél Kovács 1/1/2016')=> "कोर्नेल कोवाक्स 1/1/2016"
जीडीबल

4

PHP में यह मेरे लिए था (फ़ाइल नाम UTF8 एन्कोडेड है)

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

IE8-11, फ़ायरफ़ॉक्स और क्रोम के खिलाफ परीक्षण किया गया।
यदि ब्राउज़र फ़ाइल नाम * = utf-8 की व्याख्या कर सकता है तो यह फ़ाइल नाम के UTF8 संस्करण का उपयोग करेगा, अन्यथा यह डिकोड किए गए फ़ाइल नाम का उपयोग करेगा। यदि आपके फ़ाइल नाम में ऐसे अक्षर हैं, जिन्हें ISO-8859-1 में प्रस्तुत नहीं किया जा सकता है, तो आप iconvइसके बजाय उपयोग करने पर विचार कर सकते हैं ।


3
यद्यपि यह कोड प्रश्न का उत्तर दे सकता है, क्यों और / या कैसे का उत्तर देता है के संबंध में अतिरिक्त संदर्भ प्रदान करने से इसके दीर्घकालिक मूल्य में काफी सुधार होगा। कृपया कुछ स्पष्टीकरण जोड़ने के लिए अपने उत्तर को संपादित करें।
टोबी स्पाइट

2
वाह, ऊपर दिए गए कोड में से कोई भी उत्तर केवल उसी तरह से अस्वीकृत या क्रिटिकल नहीं हुआ। मैंने यह भी पाया कि क्यों पहले से ही अच्छी तरह से उत्तर दिया गया था: IE फ़ाइल नाम * = utf-8 की व्याख्या नहीं करता है, लेकिन फ़ाइल नाम के ISO8859-1 संस्करण की आवश्यकता है, जो यह स्क्रिप्ट प्रदान करती है। केवल आलसी को PHP के लिए काम करने का आसान कोड देना चाहता था।
गुस्ताव

मुझे लगता है कि यह कम हो गया क्योंकि सवाल विशिष्ट भाषा नहीं है लेकिन हेडर एन्कोडिंग को लागू करने के लिए छड़ी करने के लिए आरएफसी के बारे में क्या है। धन्यवाद, इस उत्तर के लिए, PHP के लिए, इस कोड ने मेरे संकटों को दूर कर दिया।
j4k3

धन्यवाद। इस सवाल का जवाब शायद कड़ाई से नहीं दिया जा सकता था, लेकिन यह वही था जो मैं देख रहा था और मुझे पायथन में इस मुद्दे को हल करने में मदद मिली।
लिंडसी साइमन

1
मुझे पूरा यकीन है कि यदि उपयोगकर्ता फ़ाइल के नाम को नियंत्रित कर सकता है तो इस कोड को एक हमले के रूप में इस्तेमाल किया जा सकता है।
अंती हापाला

3

बस एक अपडेट के बाद से मैं एक ग्राहक के मुद्दे के जवाब में आज यह सब सामान आजमा रहा था

  • जापानी के लिए कॉन्फ़िगर किए गए सफारी के अपवाद के साथ, हमारे ग्राहक द्वारा परीक्षण किए गए सभी ब्राउज़रों ने फ़ाइल नाम = text.pdf के साथ सबसे अच्छा काम किया - जहां पाठ ASP.Net/IIS द्वारा utl एन्कोडिंग के बिना utf-8 में अनुक्रमित ग्राहक मूल्य है। किसी कारण से, अंग्रेजी के लिए कॉन्फ़िगर किया गया सफारी utf-8 जापानी नाम के साथ एक फ़ाइल को ठीक से स्वीकार करेगा और सहेजेगा, लेकिन जापानी के लिए कॉन्फ़िगर किया गया एक ही ब्राउज़र utf-8 वर्णों के साथ फ़ाइल को बिना सहेजे सहेज लेगा। परीक्षण किए गए अन्य सभी ब्राउज़र url एन्कोडिंग के बिना एन्कोड किए गए फ़ाइल नाम utf-8 के साथ सबसे अच्छा / ठीक (भाषा कॉन्फ़िगरेशन की परवाह किए बिना) काम करने लगते थे।
  • मुझे Rfc5987 / 8187 को लागू करने वाला एक भी ब्राउज़र नहीं मिला । मैंने नवीनतम क्रोम के साथ परीक्षण किया, फ़ायरफ़ॉक्स प्लस IE 11 और एज बनाता है। मैंने केवल फ़ाइल नाम * = utf-8''texturlencoded.pdf के साथ हेडर सेट करने की कोशिश की, इसे दोनों फ़ाइल नाम = text.pdf के साथ सेट किया; फ़ाइल नाम * = UTF-8''texturlencoded.pdf। Rfc5987 / 8187 की एक भी विशेषता उपरोक्त में से किसी में भी सही ढंग से संसाधित होती हुई नहीं दिखाई दी।

यह एक अच्छा अपडेट है। क्या आप अपने द्वारा आजमाए गए विशिष्ट परीक्षणों के बारे में बता सकते हैं?
ब्रैड

3

PHP फ्रेमवर्क सिम्फनी 4 में $filenameFallbackहै HeaderUtils::makeDisposition। आप इस फ़ंक्शन को विवरण के लिए देख सकते हैं - यह ऊपर दिए गए उत्तरों के समान है।

उपयोग उदाहरण:

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

1

क्लासिक एएसपी समाधान

अधिकांश आधुनिक ब्राउज़र गुजर समर्थन Filenameके रूप में UTF-8अब, लेकिन के रूप में एक फाइल अपलोड समाधान मैं उपयोग कि पर आधारित था के साथ भी थी FreeASPUpload.Net (साइट अब करने के लिए मौजूद है, लिंक अंक archive.org ) इसके बारे में पार्स के रूप में काम नहीं होता बाइनरी सिंगल बाइट एएससीआईआई एन्कोडेड स्ट्रिंग्स को पढ़ने पर निर्भर करता है, जो तब तक ठीक काम करता है जब आप यूटीएफ -8 एन्कोडेड डेटा पास करते हैं जब तक कि आप एएससीआईआई का समर्थन नहीं करते।

हालाँकि मैं द्विआधारी को UTF-8 के रूप में पढ़ने और पार्स करने के लिए कोड प्राप्त करने के लिए एक समाधान खोजने में सक्षम था।

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

क्रेडिट शुद्ध एएसपी फ़ाइल अपलोड में जाता है अपने स्वयं के कोड BytesToString()से फ़ंक्शन को लागू करने से include_aspuploader.aspमैं UTF-8फ़ाइलनाम काम करने में सक्षम था ।


उपयोगी कड़ियाँ


-1

हमें वेब एप्लिकेशन में एक समान समस्या थी, और HTML से फ़ाइल नाम पढ़कर <input type="file">, और एक नए HTML में url- एन्कोडेड फ़ॉर्म में सेट करके समाप्त कर दिया <input type="hidden">। बेशक हमें "C: \ fakepath \" जैसा रास्ता निकालना था जो कि कुछ ब्राउज़रों ने वापस कर दिया है।

बेशक यह सीधे ओपी प्रश्न का उत्तर नहीं देता है, लेकिन दूसरों के लिए एक समाधान हो सकता है।


1
पूरी तरह से अलग मुद्दा है। प्रश्न डाउनलोड करने के बारे में है , आपका उत्तर अपलोड करने के बारे में है ।
Oskar Berggren

-3

मैं सामान्य रूप से फ़ाइल नाम के साथ (% xx के साथ) एनकोड करता हूं, और यह सभी ब्राउज़रों में काम करने लगता है। आप वैसे भी कुछ परीक्षण करना चाह सकते हैं।


10
मैंने कुछ में परीक्षण किया और यह सभी ब्राउज़रों में इस तरह से काम नहीं करता है, इस प्रकार प्रश्न। :)
आतिफ अजीज
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.