swift NSURLComponents के साथ% 2B में एन्कोड कैसे करें




encoding url-encoding (4)

मैं NSURLComponents का उपयोग कर रहा हूं और मुझे क्वेरी मान सही ढंग से एन्कोड करने के लिए नहीं मिल सकता है। मुझे %2B + रूप में प्रतिनिधित्व करने के लिए अंतिम URL की आवश्यकता है

let baseUrl = NSURL(string: "http://www.example.com")    
let components = NSURLComponents(URL: baseUrl, resolvingAgainstBaseURL: true)
components.queryItems = [ NSURLQueryItem(name: "name", value: "abc+def") ]
XCTAssertEqual(components!.string!, "http://www.example.com?connectionToken=abc%2Bdef")

अनुत्तीर्ण होना!

आउटपुट बराबर है:

http://www.example.com?connectionToken=abc+def 

नहीं

http://www.example.com?connectionToken=abc%2Bdef

मैंने कई रूपों की कोशिश की है और मैं इसे आउटपुट %2B पर बिल्कुल भी नहीं पा सकता


+ एक वैध वर्ण हो सकता है जब सामग्री प्रकार एप्लिकेशन / एक्स-www- NSURLComponents urlencoded है, लिंक देखें, इसलिए NSURLComponents इसे एनकोड नहीं करता है।

ऐप्पल यह भी उल्लेख:

आरएफसी 3986 निर्दिष्ट करता है कि कौन सा वर्ण एक यूआरएल के क्वेरी घटक में प्रतिशत-एन्कोडेड होना चाहिए, लेकिन उन वर्णों को व्याख्या नहीं करना चाहिए। सीमांकित कुंजी-मान जोड़े का उपयोग एक आम सम्मेलन है, लेकिन एक विनिर्देश द्वारा मानकीकृत नहीं है। इसलिए, आप इस कार्यान्वयन के अनुसरण में अन्य कार्यान्वयन के साथ अंतर-सुलभ समस्याओं का सामना कर सकते हैं।

संभावित अंतर-क्षमता समस्याओं का एक उल्लेखनीय उदाहरण यह है कि प्लस चिह्न (+) चरित्र को कैसे नियंत्रित किया जाता है:

आरएफसी 3986 के अनुसार, प्लस चिन्ह एक क्वेरी के भीतर एक वैध वर्ण है, और इसे प्रतिशत-एन्कोडेड नहीं होना चाहिए। हालांकि, यूआरआई को संबोधित करने के लिए W3C सिफारिशों के मुताबिक, प्लस चिन्ह को क्वेरी स्ट्रिंग के अंदर किसी स्थान के लिए लघुकथा के रूप में आरक्षित किया जाता है (उदाहरण के लिए, ग्रीटिंग = हैलो + दुनिया)।

यदि एक यूआरएल क्वेरी घटक में आरएफसी 3339 के अनुसार समयजोज़ ऑफसेट (उदाहरण के लिए, 2013-12-31T14: 00: 00 + 00: 00) में एक प्लस चिह्न के साथ स्वरूपित तारीख होती है, तो एक स्थान के परिणाम के रूप में प्लस चिह्न की व्याख्या करना अमान्य समय प्रारूप आरएफसी 3339 निर्दिष्ट करता है कि दिनांक कैसे स्वरूपित होनी चाहिए, लेकिन यह सलाह नहीं देता कि प्लस चिह्न एक यूआरएल में प्रतिशत-एन्कोडेड होना चाहिए। इस यूआरएल को प्राप्त करने के कार्यान्वयन के आधार पर, आपको प्लस साइन वर्ण को पूर्वनिर्धारित प्रतिशत-सांकेतिक शब्दों में बदलना पड़ सकता है

एक विकल्प के रूप में, अधिक मजबूत डेटा-आदान-प्रदान प्रारूप में जटिल और / या संभावित रूप से समस्याग्रस्त डेटा को एन्कोडिंग पर विचार करें, जैसे JSON या XML

निष्कर्ष है कि आप '+' को या नहीं एन्कोड कर सकते हैं

मेरी राय में, NSURLComponents केवल एन्कोड वर्ण है जो यह सुनिश्चित करता है कि एन्कोड किया जाना चाहिए, जैसे '&', '=' या चीनी अक्षर जैसे '你' '好', यह एन्कोड नहीं करता है कि वर्ण एनकोड हो सकता है या नहीं सामग्री प्रकार के लिए, जैसा कि मैंने ऊपर उल्लेखित '+' इसलिए यदि आपको लगता है कि आपको '+' को एन्कोड करना है या आपका सर्वर सही ढंग से पार्स नहीं कर सकता है, तो आप नीचे कोड का उपयोग कर सकते हैं

मैं तेजी से नहीं जानता, इसलिए मैं सिर्फ उद्देश्य-सी कोड प्रदान करता हूं, इसके लिए खेद है।

- (NSString *)URLEncodingValue:(NSString *)value
{
    NSCharacterSet *set = [NSCharacterSet URLQueryAllowedCharacterSet];
    NSMutableCharacterSet *mutableQueryAllowedCharacterSet = [set mutableCopy];
    [mutableQueryAllowedCharacterSet removeCharactersInString:@"!*'();:@&=+$,/?%#[]"];
    return [value stringByAddingPercentEncodingWithAllowedCharacters:mutableQueryAllowedCharacterSet];
}

! * '();: @ @ = = $, /?% # [] आरएफसी 3986 में परिभाषित आरक्षित वर्ण हैं, अगर कोड' + 'को एन्कोड करना चाहते हैं, तो कोड उन सबको एनकोड करेगा, मान पैरामीटर में दिखाई देगा, बस की जगह !*'();:@&=+$,/?%#[] साथ +


यह एक ऐप्पल बग है इसके बजाय उपयोग करें

NSString -stringByAddingPercentEncodingWithAllowedCharacters:

साथ में

NSCharacterSet +URLQueryAllowedCharacterSet

रडार 24076063 से मेरा जवाब यह बताता है कि यह कैसे काम करता है (पाठ की थोड़ी सफाई के साथ):

'+' वर्ण क्वेरी घटक में कानूनी है इसलिए इसे प्रतिशत-एन्कोडेड होने की आवश्यकता नहीं है।

कुछ सिस्टम '+' को एक स्थान के रूप में उपयोग करते हैं और '+' को प्लस चरित्र की आवश्यकता होती है, जो प्रतिशत-एन्कोडेड होती है। हालांकि, उस तरह की दो चरण एन्कोडिंग (कनवर्टिंग प्लस को% 2 बी पर हस्ताक्षर करने और फिर स्थान को प्लस साइन करने के लिए परिवर्तित करना) त्रुटियों की संभावना है क्योंकि यह आसानी से एन्कोडिंग समस्याओं की ओर जाता है यह भी टूट जाता है कि यूआरएल सामान्यीकृत है (यूआरएल की वाक्यविन्यास सामान्यीकरण में सभी अनावश्यक प्रतिशत-एन्कोडिंग हटाने शामिल हैं - आरएफसी 3 9 6 खंड 6.2.2.2 देखें)।

इसलिए, अगर आपको उस सर्वर की वजह से उस व्यवहार की आवश्यकता है, जिससे आपका कोड बात कर रहा है, तो आप अपने आप को अतिरिक्त परिवर्तन (एस) को संभाल लेंगे यहां कोड का स्निपेट दिया गया है जो दर्शाता है कि आपको दोनों तरीकों से क्या करना है:

NSURLComponents *components = [[NSURLComponents alloc] init];
NSArray *items = [NSArray arrayWithObjects:[NSURLQueryItem queryItemWithName:@"name" value:@"Value +"], nil];
components.queryItems = items;
NSLog(@"URL queryItems: %@", [components queryItems]);
NSLog(@"URL string before: %@", [components string]);

// Replace all "+" in the percentEncodedQuery with "%2B" (a percent-encoded +) and then replace all "%20" (a percent-encoded space) with "+"
components.percentEncodedQuery = [[components.percentEncodedQuery stringByReplacingOccurrencesOfString:@"+" withString:@"%2B"] stringByReplacingOccurrencesOfString:@"%20" withString:@"+"];
NSLog(@"URL string after: %@", [components string]);

// This is the reverse if you receive a URL with a query in that form and want to parse it with queryItems
components.percentEncodedQuery = [[components.percentEncodedQuery stringByReplacingOccurrencesOfString:@"+" withString:@"%20"] stringByReplacingOccurrencesOfString:@"%2B" withString:@"+"];
NSLog(@"URL string back: %@", [components string]);
NSLog(@"URL queryItems: %@", [components queryItems]);

आउटपुट है:

URL queryItems: (
    "<NSURLQueryItem 0x100502460> {name = name, value = Value +}"
)

URL string before: ?name=Value%20+

URL string after: ?name=Value+%2B

URL string back: ?name=Value%20+

URL queryItems: (
    "<NSURLQueryItem 0x1002073e0> {name = name, value = Value +}"
)

जैसा कि अन्य उत्तरों का उल्लेख है, डिफ़ॉल्ट रूप से "+" आईओएस पर एन्कोड नहीं किया गया है लेकिन अगर आपके सर्वर को यह एन्कोड करने की आवश्यकता है, तो इसे कैसे करें:

var comps = URLComponents(url: self, resolvingAgainstBaseURL: true)
comps?.queryItems = [URLQueryItem(name: "name", value: "abc+def")]
comps?.percentEncodedQuery = comps?.percentEncodedQuery?.replacingOccurrences(of: "+", with: "%2B")






url-encoding