it-swarm.dev

كيف يمكنني ترميز URL سلسلة

لدي سلسلة عناوين URL (NSString) بمسافات وأحرف &. كيف يمكنني تشفير url للسلسلة بأكملها (بما في ذلك حرف علامة الضم والمسافات &

182
xonegirlz

لسوء الحظ ، stringByAddingPercentEscapesUsingEncoding لا يعمل دائمًا بنسبة 100٪. إنه يشفر أحرفًا غير عنوان URL ، لكنه يترك الأحرف المحجوزة (مثل الشرطة المائلة / وعلامة الضم &) وحدها. يبدو أن هذا هو خطأ تعرفه Apple ، لكن بما أنها لم تثبته بعد ، فقد استخدمت هذه الفئة لترميز سلسلة عناوين URL:

@implementation NSString (NSString_Extended)

- (NSString *)urlencode {
    NSMutableString *output = [NSMutableString string];
    const unsigned char *source = (const unsigned char *)[self UTF8String];
    int sourceLen = strlen((const char *)source);
    for (int i = 0; i < sourceLen; ++i) {
        const unsigned char thisChar = source[i];
        if (thisChar == ' '){
            [output appendString:@"+"];
        } else if (thisChar == '.' || thisChar == '-' || thisChar == '_' || thisChar == '~' || 
                   (thisChar >= 'a' && thisChar <= 'z') ||
                   (thisChar >= 'A' && thisChar <= 'Z') ||
                   (thisChar >= '0' && thisChar <= '9')) {
            [output appendFormat:@"%c", thisChar];
        } else {
            [output appendFormat:@"%%%02X", thisChar];
        }
    }
    return output;
}

تستخدم مثل هذا:

NSString *urlEncodedString = [@"SOME_URL_GOES_HERE" urlencode];

// Or, with an already existing string:
NSString *someUrlString = @"someURL";
NSString *encodedUrlStr = [someUrlString urlencode];

هذا يعمل أيضا:

NSString *encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
                            NULL,
                            (CFStringRef)unencodedString,
                            NULL,
                            (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                            kCFStringEncodingUTF8 );

بعض القراءة الجيدة عن الموضوع:

الهدف ج في المئة فون ترميز سلسلة؟
تشفير الهدف- C و Swift URL

http://cybersam.com/programming/proper-url-percent-encoding-in-ios
https://devforums.Apple.com/message/15674#15674http://simonwoodside.com/weblog/2009/4/22/how_to_really_url_encode/

284
chown

هذا قد يكون مفيدا

NSString *sampleUrl = @"http://www.google.com/search.jsp?params=Java Developer";
NSString* encodedUrl = [sampleUrl stringByAddingPercentEscapesUsingEncoding:
 NSUTF8StringEncoding];

بالنسبة لنظام التشغيل iOS 7+ ، الطريقة الموصى بها هي:

NSString* encodedUrl = [sampleUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];

يمكنك اختيار مجموعة الأحرف المسموح بها وفقًا لمتطلبات مكون URL.

124
Nishant

تمت إضافة واجهات برمجة تطبيقات جديدة منذ تحديد الإجابة ؛ يمكنك الآن استخدام NSURLUtilities. نظرًا لأن أجزاء مختلفة من عناوين URL تسمح بأحرف مختلفة ، استخدم مجموعة الأحرف القابلة للتطبيق. المثال التالي يشفر للتضمين في سلسلة الاستعلام:

encodedString = [myString stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLQueryAllowedCharacterSet];

لتحويل "&" على وجه التحديد ، ستحتاج إلى إزالته من مجموعة طلبات url أو استخدام مجموعة مختلفة ، لأن "&" مسموح به في استعلام URL:

NSMutableCharacterSet *chars = NSCharacterSet.URLQueryAllowedCharacterSet.mutableCopy;
[chars removeCharactersInRange:NSMakeRange('&', 1)]; // %26
encodedString = [myString stringByAddingPercentEncodingWithAllowedCharacters:chars];
89
Peter DeWeese

تحديث ios 7

NSString *encode = [string stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];

NSString *decode = [encode stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
14
Underdog

لقد اخترت استخدام مكالمة CFURLCreateStringByAddingPercentEscapes كما هو موضح في الإجابة المقبولة ، ولكن في أحدث إصدار من XCode (و IOS) ، نتج عن خطأ ، لذلك استخدمت ما يلي بدلاً من ذلك:

NSString *apiKeyRaw = @"79b|7Qd.jW=])(fv|M&W0O|3CENnrbNh4}2E|-)J*BCjCMrWy%dSfGs#A6N38Fo~";

NSString *apiKey = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)apiKeyRaw, NULL, (CFStringRef)@"!*'();:@&=+$,/?%#[]", kCFStringEncodingUTF8));
8
Mike Purcell

حاول استخدامstringByAddingPercentEncodingWithAllowedCharactersطريقة مع[NSCharacterSet URLUserAllowedCharacterSet]ستغطي جميع الحالات

ج موضوعية

NSString *value = @"Test / Test";
value = [value stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLUserAllowedCharacterSet]];

سريع

var value = "Test / Test"
value.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLUserAllowedCharacterSet())

انتاج |

Test%20%2F%20Test

6
Alex

بعد قراءة جميع الإجابات حول هذا الموضوع و ( wrong ) مقبول ، أريد إضافة مساهمي.

إذا كانالهدف هو iOS7 + ، وفي عام 2017 يجب أن يكون ذلك لأن XCode يجعل من الصعب حقًا تقديم التوافق بموجب iOS8 ، وأفضل طريقة وخيط آمن وسريع وسيقوم AMD بدعم UTF-8 الكامل للقيام بذلك هو:

(رمز الهدف جيم)

@implementation NSString (NSString_urlencoding)

- (NSString *)urlencode {
    static NSMutableCharacterSet *chars = nil;
    static dispatch_once_t pred;

    if (chars)
        return [self stringByAddingPercentEncodingWithAllowedCharacters:chars];

    // to be thread safe
    dispatch_once(&pred, ^{
        chars = NSCharacterSet.URLQueryAllowedCharacterSet.mutableCopy;
        [chars removeCharactersInString:@"!*'();:@&=+$,/?%#[]"];
    });
    return [self stringByAddingPercentEncodingWithAllowedCharacters:chars];
}
@end

سيؤدي ذلك إلى تمديد NSString ، واستبعاد الأحرف الممنوعة لـ RFC ، ودعم أحرف UTF-8 ، ويتيح لك استخدام أشياء مثل:

NSString *myusername = "I'm[evil]&want(to)break!!!$->àéìòù";
NSLog(@"Source: %@ -> Dest: %@", myusername, [myusername urlencode]);

التي ستطبع على وحدة التحكم التصحيح الخاصة بك:

المصدر: أنا [شرير] وأريد كسر (!)! - $ -> àéìòù -> المسافة: أنا٪ 27m٪ 5Bevil٪ 5D٪ 26want٪ 28to٪ 29break٪ 21٪ 21٪ 21٪ 24-٪ 3E٪ C3 ٪ A0٪ C3٪ A9٪ C3٪ AC٪ C3٪ B2٪ C3٪ B9

... لاحظ أيضًا استخدام dispatch_once لتجنب عمليات التهيئة المتعددة في بيئات متعددة مؤشرات الترابط.

5
gabry

استخدم NSURLComponents لتشفير معلمات HTTP GET:

    var urlComponents = NSURLComponents(string: "https://www.google.de/maps/")!
    urlComponents.queryItems = [
        NSURLQueryItem(name: "q", value: String(51.500833)+","+String(-0.141944)),
        NSURLQueryItem(name: "z", value: String(6))
    ]
    urlComponents.URL     // returns https://www.google.de/maps/?q=51.500833,-0.141944&z=6

http://www.ralfebert.de/snippets/ios/encoding-nsurl-get-parameters/

4
Ralf Ebert

إليك مقاربة مرنة جاهزة للإنتاج في Swift 4 :

public extension CharacterSet {

    public static let urlQueryParameterAllowed = CharacterSet.urlQueryAllowed.subtracting(CharacterSet(charactersIn: "&?"))

    public static let urlQueryDenied           = CharacterSet.urlQueryAllowed.inverted()
    public static let urlQueryKeyValueDenied   = CharacterSet.urlQueryParameterAllowed.inverted()
    public static let urlPathDenied            = CharacterSet.urlPathAllowed.inverted()
    public static let urlFragmentDenied        = CharacterSet.urlFragmentAllowed.inverted()
    public static let urlHostDenied            = CharacterSet.urlHostAllowed.inverted()

    public static let urlDenied                = CharacterSet.urlQueryDenied
        .union(.urlQueryKeyValueDenied)
        .union(.urlPathDenied)
        .union(.urlFragmentDenied)
        .union(.urlHostDenied)


    public func inverted() -> CharacterSet {
        var copy = self
        copy.invert()
        return copy
    }
}



public extension String {
    func urlEncoded(denying deniedCharacters: CharacterSet = .urlDenied) -> String? {
        return addingPercentEncoding(withAllowedCharacters: deniedCharacters.inverted())
    }
}

مثال للاستخدام:

print("Hello, World!".urlEncoded()!)
print("You&Me?".urlEncoded()!)
print("#Blessed 100%".urlEncoded()!)
print("Pride and Prejudice".urlEncoded(denying: .uppercaseLetters)!)

انتاج:

Hello,%20World!
You%26Me%3F
%23Blessed%20100%25
%50ride and %50rejudice
4
Ben Leggiero

رمز سريع يستند إلى chown 'ق objc الإجابة في هذا الموضوع.

extension String {
    func urlEncode() -> String {
        return CFURLCreateStringByAddingPercentEscapes(
            nil,
            self,
            nil,
            "!*'();:@&=+$,/?%#[]",
            CFStringBuiltInEncodings.UTF8.rawValue
        )
    }
}
4
neoneye

ساعدني هذا الرمز في ترميز الأحرف الخاصة

NSString* encPassword = [password stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet alphanumericCharacterSet]];
3
Rupesh Baldania

في سويفت 3:

// exclude alpha and numeric == "full" encoding
stringUrl = stringUrl.addingPercentEncoding(withAllowedCharacters: .alphanumerics)!;

// exclude hostname and symbols &,/ and etc
stringUrl = stringUrl.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!;
2
sea-kg

في سويفت 3 ، يرجى المحاولة أدناه:

let stringURL = "YOUR URL TO BE ENCODE";
let encodedURLString = stringURL.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
print(encodedURLString)

نظرًا لأن stringByAddingPercentEscapesUsingEncoding يشفر أحرفًا غير عناوين URL ولكنه يترك الأحرف المحجوزة (مثل !*'();:@&=+$,/?%#[]) ، يمكنك تشفير عنوان url مثل التعليمة البرمجية التالية:

let stringURL = "YOUR URL TO BE ENCODE";
let characterSetTobeAllowed = (CharacterSet(charactersIn: "!*'();:@&=+$,/?%#[] ").inverted)
if let encodedURLString = stringURL.addingPercentEncoding(withAllowedCharacters: characterSetTobeAllowed) {
    print(encodedURLString)
}
2
Dinesh
-(NSString *)encodeUrlString:(NSString *)string {
  return CFBridgingRelease(
                    CFURLCreateStringByAddingPercentEscapes(
                        kCFAllocatorDefault,
                        (__bridge CFStringRef)string,
                        NULL,
                        CFSTR("!*'();:@&=+$,/?%#[]"),
                        kCFStringEncodingUTF8)
                    );
}

وفقًا لـ المدونة التالية

1
Anton Kashpor

في حالتي حيث كان المكون الأخير هو الحروف العربية ، قمت بما يلي في Swift 2.2:

extension String {

 func encodeUTF8() -> String? {

    //If I can create an NSURL out of the string nothing is wrong with it
    if let _ = NSURL(string: self) {

        return self
    }

    //Get the last component from the string this will return subSequence
    let optionalLastComponent = self.characters.split { $0 == "/" }.last


    if let lastComponent = optionalLastComponent {

        //Get the string from the sub sequence by mapping the characters to [String] then reduce the array to String
        let lastComponentAsString = lastComponent.map { String($0) }.reduce("", combine: +)


        //Get the range of the last component
        if let rangeOfLastComponent = self.rangeOfString(lastComponentAsString) {
            //Get the string without its last component
            let stringWithoutLastComponent = self.substringToIndex(rangeOfLastComponent.startIndex)


            //Encode the last component
            if let lastComponentEncoded = lastComponentAsString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.alphanumericCharacterSet()) {


            //Finally append the original string (without its last component) to the encoded part (encoded last component)
            let encodedString = stringWithoutLastComponent + lastComponentEncoded

                //Return the string (original string/encoded string)
                return encodedString
            }
        }
    }

    return nil;
}
}

الاستعمال:

let stringURL = "http://xxx.dev.com/endpoint/nonLatinCharacters"

if let encodedStringURL = stringURL.encodeUTF8() {

    if let url = NSURL(string: encodedStringURL) {

      ...
    }

} 
1
Bobj-C

نصيحة Apple ، في ملاحظات الإصدار 10.11 ، هي:

إذا كنت بحاجة إلى ترميز سلسلة URL بالكامل في المئة ، فيمكنك استخدام هذا الرمز لتشفير NSString المقصود منه أن يكون عنوان URL (في urlStringToEncode):

NSString *percentEncodedURLString =
  [[NSURL URLWithDataRepresentation:[urlStringToEncode dataUsingEncoding:NSUTF8StringEncoding] relativeToURL:nil] relativeString];
1
nithinbhaktha

واجهت مشكلة مماثلة في تمرير سلاسل معقدة كمعلمة POST. يمكن أن تحتوي سلاسلي على أحرف آسيوية ومسافات وعلامات اقتباس وجميع أنواع الأحرف الخاصة. كان الحل الذي وجدته في النهاية هو تحويل السلسلة إلى سلسلة مطابقة لليونيكود ، على سبيل المثال "Hu0040Hu0020Hu03f5 ...." باستخدام [NSString stringWithFormat: @ "Hu٪ 04x"، [string characterAtIndex: i]] للحصول على Unicode من كل حرف في السلسلة الأصلية. ويمكن القيام بنفس الشيء في جافا.

يمكن تمرير هذه السلسلة بأمان كمعلمة POST.

على جانب الخادم (PHP) ، أغير كل "H" إلى "\" وأمرر السلسلة الناتجة إلى json_decode. الخطوة الأخيرة هي الهروب من علامات الاقتباس المفردة قبل تخزين السلسلة في MySQL.

بهذه الطريقة يمكنني تخزين أي سلسلة UTF8 على الخادم الخاص بي.

0
Georges

// هذا بدون اختبار

NSMutableCharacterSet* set = [[NSCharacterSet alphanumericCharacterSet] mutableCopy];
[set addCharactersInString:@"-_.~"];
NSString *encode = [test stringByAddingPercentEncodingWithAllowedCharacters:set];
0
Achilles Wang

هذا واحد يعمل بالنسبة لي.

func stringByAddingPercentEncodingForFormData(plusForSpace: Bool=false) -> String? {
    let unreserved = "*-._"
    let allowed = NSMutableCharacterSet.alphanumericCharacterSet()
    allowed.addCharactersInString(unreserved)

    if plusForSpace {
        allowed.addCharactersInString(" ")
    }

    var encoded = stringByAddingPercentEncodingWithAllowedCharacters(allowed)
    if plusForSpace {
        encoded = encoded?.stringByReplacingOccurrencesOfString(" ",
                                                                withString: "+")
    }
    return encoded
}

لقد وجدت الوظيفة أعلاه من هذا الرابط: http://useyourloaf.com/blog/how-to-percent-encode-a-url-string/

يمكنك أيضًا استخدام هذه الوظيفة مع امتداد Swift. واسمحوا لي أن أعرف إذا كان هناك أي مشكلة.

0
Gaurav Singla

بالنسبة إلى معلمات طلب البحث المرمّزة على شكل www ، قمت بعمل فئة على NSString:

- (NSString*)WWWFormEncoded{
     NSMutableCharacterSet *chars = NSCharacterSet.alphanumericCharacterSet.mutableCopy;
     [chars addCharactersInString:@" "];
     NSString* encodedString = [self stringByAddingPercentEncodingWithAllowedCharacters:chars];
     encodedString = [encodedString stringByReplacingOccurrencesOfString:@" " withString:@"+"];
     return encodedString;
}
0
Pete Kamm