【问题标题】:iOS: Issue with ampersand in the URL stringiOS:URL 字符串中的 & 符号问题
【发布时间】:2010-10-16 20:49:53
【问题描述】:

我们如何在 URL 中传递字符串 Mr.X & Mr.Y。

我已经尝试过了,但是这个可以处理所有字符,除了 & 符号。

[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]

【问题讨论】:

    标签: ios objective-c nsurl


    【解决方案1】:

    CFURLCreateStringByAddingPercentEscapes 已被弃用(自 iOS9 起),那么如何仅修改 URLQueryAllowedCharacterSet 以删除保留字符,从而使它们能够相对有效地进行百分比编码?

    - (NSString *)URLQueryValueEncodedString:(NSString *)string {
        static NSMutableCharacterSet *_allowedCharacterSet = nil;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            NSString *reservedCharacters = @"=,!$&'()*+;@?\r\n\"<>#\t :/[]%";
            _allowedCharacterSet = [NSCharacterSet URLQueryAllowedCharacterSet].mutableCopy;
            [_allowedCharacterSet removeCharactersInString:reservedCharacters];
        });
    
        return [string stringByAddingPercentEncodingWithAllowedCharacters:_allowedCharacterSet];
    }
    

    【讨论】:

      【解决方案2】:

      甚至更短:

      @implementation NSString (Escaping)
      - (NSString*)stringWithPercentEscape {            
          return [(NSString *) CFURLCreateStringByAddingPercentEscapes(
              NULL, 
              (CFStringRef)[[self mutableCopy] autorelease], 
              NULL, 
              CFSTR("=,!$&'()*+;@?\n\"<>#\t :/"),
              kCFStringEncodingUTF8) autorelease];
      }
      @end
      

      这里又是一个符合 ARC 的内联函数助手:

      #if __has_feature(objc_arc)
      static inline NSString *hxURLEscape(NSString *v) {
          static CFStringRef _hxURLEscapeChars = CFSTR("=,!$&'()*+;@?\r\n\"<>#\t :/");
          return ((__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(
              NULL, 
              (__bridge CFStringRef)[v mutableCopy], 
              NULL, 
              _hxURLEscapeChars, 
              kCFStringEncodingUTF8));
      }
      #endif
      

      【讨论】:

      • 请看下面罗杰的回答。虽然这个解决方案是一个很好的通用答案,但它不是 iOS 2.2 版的完整 URL 编码实现。如果有人有任何关于此问题在以后的 iOS 版本中得到修复的其他信息,请在此处发表评论。
      • 确实,我认为我们根本不需要复制它,可以将[[self mutableCopy] autorelease] 替换为self。有关它的更多详细信息,请参阅 CFURLCreateStringByAddingPercentEscapes developer.apple.com/library/mac/#documentation/CoreFoundation/… 的文档
      【解决方案3】:

      stringByAddingPercentEscapesUsingEncoding 也不能与+ 一起正常工作。

      这是一个更简单的解决方案:

      [[[urlString stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding] stringByReplacingOccurrencesOfString:@"&" withString:@"%26"] stringByReplacingOccurrencesOfString:@"+" withString:@"%2b"];
      

      【讨论】:

        【解决方案4】:

        -stringByAddingPercentEscapesUsingEncoding: 不执行完整的转义编码。您应该使用-replaceOccurrencesOfString:withString:手动添加编码

        这是最初在https://devforums.apple.com/message/15674#15674 建议的完整列表(反映 Gamecat 的列表)。正如 Nick 指出的那样,这很昂贵,所以不要简单地包含完整列表而不考虑您对转义的真正要求。

        NSMutableString *escaped = [actionString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];   
        [escaped replaceOccurrencesOfString:@"$" withString:@"%24" options:NSCaseInsensitiveSearch range:wholeString];
        [escaped replaceOccurrencesOfString:@"&" withString:@"%26" options:NSCaseInsensitiveSearch range:wholeString];
        [escaped replaceOccurrencesOfString:@"+" withString:@"%2B" options:NSCaseInsensitiveSearch range:wholeString];
        [escaped replaceOccurrencesOfString:@"," withString:@"%2C" options:NSCaseInsensitiveSearch range:wholeString];
        [escaped replaceOccurrencesOfString:@"/" withString:@"%2F" options:NSCaseInsensitiveSearch range:wholeString];
        [escaped replaceOccurrencesOfString:@":" withString:@"%3A" options:NSCaseInsensitiveSearch range:wholeString];
        [escaped replaceOccurrencesOfString:@";" withString:@"%3B" options:NSCaseInsensitiveSearch range:wholeString];
        [escaped replaceOccurrencesOfString:@"=" withString:@"%3D" options:NSCaseInsensitiveSearch range:wholeString];
        [escaped replaceOccurrencesOfString:@"?" withString:@"%3F" options:NSCaseInsensitiveSearch range:wholeString];
        [escaped replaceOccurrencesOfString:@"@" withString:@"%40" options:NSCaseInsensitiveSearch range:wholeString];
        [escaped replaceOccurrencesOfString:@" " withString:@"%20" options:NSCaseInsensitiveSearch range:wholeString];
        [escaped replaceOccurrencesOfString:@"\t" withString:@"%09" options:NSCaseInsensitiveSearch range:wholeString];
        [escaped replaceOccurrencesOfString:@"#" withString:@"%23" options:NSCaseInsensitiveSearch range:wholeString];
        [escaped replaceOccurrencesOfString:@"<" withString:@"%3C" options:NSCaseInsensitiveSearch range:wholeString];
        [escaped replaceOccurrencesOfString:@">" withString:@"%3E" options:NSCaseInsensitiveSearch range:wholeString];
        [escaped replaceOccurrencesOfString:@"\"" withString:@"%22" options:NSCaseInsensitiveSearch range:wholeString];
        [escaped replaceOccurrencesOfString:@"\n" withString:@"%0A" options:NSCaseInsensitiveSearch range:wholeString];
        

        此代码肯定会对您的 URL 进行哈希处理。

        【讨论】:

        • 我相信正确的代码会更像 NSMutableString *escaped = [NSMutableString stringWithString:[actionString ...]];和 NSMakeRange(0, [转义长度])] 而不是 WholeString。
        • 这个代价很大,CFURLCreateStringByAddingPercentEscapes() 更好。
        • CFURLCreateStringByAddingPercentEscapes 没有和 stringByAddingPercentEscapesUsingEncoding 一样的问题吗?
        【解决方案5】:

        在 URL 中,和号是受保护的关键字,表示包含查询字符串变量。你不能把它作为价值本身的一部分。您需要将其更改为其他内容。

        这里是 StackOverflow 上提出的相同问题的链接:ASP.Net URLEncode Ampersand for use in Query String

        【讨论】:

          【解决方案6】:

          使用 %26 作为 url 转义。

          其他转义:

          $  %24
          &  %26
          +  %2B
          ,  %2C
          /  %2F
          :  %3A
          ;  %3B
          =  %3D
          ?  %3F
          @  %40
          

          【讨论】:

          • 所以如果我执行以下操作,我是对的 [statusTextField.text stringByReplacingOccurrencesOfString:@"&" withString:@"%26"] 并且在我的服务器端我将 %26 替换为 & 并存储在分贝。
          猜你喜欢
          • 2011-05-20
          • 1970-01-01
          • 1970-01-01
          • 2023-03-28
          • 2011-09-25
          • 2010-12-07
          • 1970-01-01
          • 1970-01-01
          • 2019-09-09
          相关资源
          最近更新 更多