zoukankan      html  css  js  c++  java
  • Swift URL encode

    前言

    在WEB前端开发,服务器后台开发,或者是客户端开发中,对URL进行编码是一件很常见的事情,但是由于各个年代的RFC文档中的内容一直在变化,一些年代久远的代码就对URL编码和解码的规则和现在的有一些区别。

    在1994年订制的RFC1738文档中,对字符串中的除了- _ .之外的所有非字母数字字符都替换成百分号(%)后跟两位十六进制数,十六进制数中字母必须为大写。

    在2005年定义的RFC3986中,将针对- _.~四个字符之外的所有非字母数字字符进行百分号编码。当然 根据URL的类型不同,有也一部分预留字符不需要进行编码,例如查询的URL中可以包含? /字符,不需要转义。更详细文档的可以查看RFC 3986

    Swift url encode

    addingPercentEncoding(withAllowedCharacters:是iOS7之后出现的新API用于url encode

    标准转码

    所有类型的URL中,"-_.~"都不应该被转码

    var str = "-_.~"
    var encodeStr = str.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
    print(encodeStr ?? "") // -_.~
    
    var str = "#"
    var encodeStr = str.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
    print(encodeStr ?? "") // %23
    

    CharacterSet

    CharacterSet是一个结构体,CharacterSet.urlHostAllowed等预制类型包含了所有不需要被转码的字符,反过来说就是指明了需要被转码的字符。CharacterSet类中提供了一些常用的URL转码的类型:

    * CharacterSet.urlHostAllowed: 被转义的字符有  "#%/<>?@^`{|}
    * CharacterSet.urlPathAllowed: 被转义的字符有  "#%;<>?[]^`{|}
    * CharacterSet.urlUserAllowed: 被转义的字符有   #%/<>?@^`{|}
    * CharacterSet.urlQueryAllowed: 被转义的字符有  "#%<>[]^`{|}
    * CharacterSet.urlPasswordAllowed 被转义的字符有 "#%/:<>?@[]^`{|}
    

    为什么说CharacterSet.urlHostAllowed包含的是所有不需要被转码的字符,可以用两句代码验证:

    let unicode = "1".unicodeScalars.flatMap{ $0 }[0]
    
    print(CharacterSet.urlHostAllowed.contains(unicode)) //输出TRUE
    

    所以,自定义转码字符的集合应该取反字符集:

    let str2 = "#/%/<>?@"
    let custom = CharacterSet(charactersIn: "#").inverted
    let result = str2.addingPercentEncoding(withAllowedCharacters: custom) ?? ""
    
    print(result) //输出 %23/%/<>?@
    

    可以看到只有#被编码。在一些特殊的需求中会用到自定义编码集合,例如BASE64转码后的URL编码。

    Objective-C url encode

    API调用都是一样的,不过网上流传的比较多的是用的C API

    NSString *ciphertext = @"saf#*&";        
    NSCharacterSet *set = [[NSCharacterSet characterSetWithCharactersInString:@"!*'();:@&=+$,/?%#[]"] invertedSet];
            
    NSString *resultString = [ciphertext stringByAddingPercentEncodingWithAllowedCharacters: set];
    

    C API

    NSString *ciphertext = @"saf#*&";
    NSString *encodedStr = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes
                                                         (kCFAllocatorDefault,
                                                          (CFStringRef)ciphertext,
                                                          NULL,
                                                          CFSTR("!*'();:@&=+$,/?%#[]"),
                                                          kCFStringEncodingUTF8));
  • 相关阅读:
    (转载)你好,C++(25)函数调用和它背后的故事5.1.2 函数调用机制
    (转载)你好,C++(24)好大一个箱子!5.1.1 函数的声明和定义
    (转载)你好,C++(23) 4.4.2 工资程序成长记:用数组处理批量数据,用循环结构执行重复动作
    (转载)你好,C++(22) 排排坐,吃果果——4.3.3 for循环:某个范围内…每个都…
    【NOI2002T4】荒岛野人-扩展欧几里得
    【POJ1743】Musical Theme-后缀数组+二分答案
    【POJ1743】Musical Theme-后缀数组+二分答案
    【NOI2014T1】起床困难综合症-贪心+位运算
    【NOI2014T1】起床困难综合症-贪心+位运算
    【APIO2012T1】派遣-贪心+左偏树
  • 原文地址:https://www.cnblogs.com/luoxiaofu/p/7110011.html
Copyright © 2011-2022 走看看