作者|泽时钦

来源|

URL编码_编码urf-8的不可映射字符_编码url是什么意思

一、URL含义 1、URL定义

URL是 的缩写,是互联网上可用资源的位置和访问方法的简明表示。 它是 上标准资源的地址。 上的每个文件都有一个唯一的 URL,其中包含指示文件位置以及浏览器应如何处理该文件的信息。 基本URL包括模式(或协议)、服务器名称(或IP地址)、路径和文件名以及参数,例如“协议://授权/路径查询?参数”。

**URL 与 URI**

许多人混淆了这两个术语。

• URL:(/ 的缩写,统一资源定位符)。

• URI:(统一资源标识符的缩写)。

对于URI来说,具体结构如下:

编码url是什么意思_URL编码_编码urf-8的不可映射字符

URI 是 URL 的较低级别抽象,是一种字符串文字标准。 URL 是 URI 的子集。

URI 表示请求服务器的路径,定义了此类资源。 URL还描述了如何访问这个资源()。

网址百度百科[1]

2. URL字符编码

1. URL编码-从到%ff[2]

2. HTML特殊字符编码对照表[3]

2. URL编码

1. 为什么要进行代码转义

推荐阅读:字符编码:ASCII和UTF-8的区别[4]

世界上有很多种编码方法。 相同的二进制数可以解释为不同的符号,不同的编码方式可以解码为乱码,给数据传输和读取造成很大障碍。 随着互联网的出现,计算机科学领域需要使用统一的字符编码(、、)作为行业标准。 它是互联网的统一符号集。 它只规定了符号唯一的二进制代码值,但没有规定这个二进制代码应该如何存储。 UTF-8 是一种特定的可变长度字符编码。 UTF-8 使用 1 到 4 个字节对字符进行编码。 它是互联网上应用最广泛的实现方法。 其他实现还有UTF-16(字符用两个字节或四个字节表示)和UTF-32(字符用四个字节表示),但在互联网上基本不使用。

注意:UTF-8是其中一种实现方式。

比如汉字:

• 代码值:中

• URL 编码 (UTF-8):%e4%b8%ad

2. URL编码规则

url编码通常也称为百分号编码,编码方法很简单,使用%百分号加两个字符——代表一个字节的十六进制形式。 URL编码默认使用的字符集是US-ASCII。 比如US-ASCII码中a对应的字节是0x61,那么Url编码就会得到%61,我们在地址栏输入%61%62%63,其实就相当于在互联网。 再比如@符号在ASCII字符集中对应的字节是0x40,经过Url编码后得到的值为%40。

对于非ASCII字符,需要使用ASCII字符集的超集对对应的字节进行编码,然后对每个字节进行百分比编码。 对于字符,RFC文档建议使用UTF-8编码得到对应的字节,然后对每个字节进行百分比编码。 例如“中文”使用UTF-8字符集得到的字节为0xE4 0xB8 0xAD 0xE6 0x96 0x87,Url编码后得到“%E4%B8%AD%E6%96%87”。

3. URL不需要编码字符

HTTP URL 使用的编码规范。 该文档规定URL中只允许使用以下四种类型:

1. 英文字母(az AZ)

2. 数字(0-9)

3. -_.~ 4个特殊字符

4、所有保留字符,以下字符指定为保留字符(英文字符):

! * '(); : @ & = + $ , / ? #[]

5、编码标志符号%

URL 编码使用“%”后跟两个十六进制数字来替换非 ASCII 字符。 中文是三种编码的组合。 十六进制格式用于在浏览器和插件中显示非标准字母和字符。

4. URL中需要编码的字符

URL编码的原理是用安全字符(没有特殊用途或意义的可打印字符)来表示不安全字符。

4.1. 非 URL 定义的字符

URL 中不能包含任何非 ASCII 字符,例如中文字符、希腊字符、拉丁字符等。 如果客户端浏览器和服务器浏览器支持的字符集不同,中文可能会出现乱码。

4.2. 导致歧义的保留字符

设置URL拼接参数或路径时,拼接后的普通字符串中含有保留字符,可能会造成二义性。 URL参数字符串以key=value等键值对的形式传递,键值对之间用&符号分隔。 例如,宝洁公司的缩写是P&G。 如果需要作为参数传递,name=P&G&t=26,因为参数中多了一个&,必然会导致接收URL的服务器解析错误,所以必须对二义性的&符号进行转义和编码。

一些保留字符及其URL编码

URL编码_编码url是什么意思_编码urf-8的不可映射字符

如果需要在URL中使用特殊字符或中文字符,则需要将这些特殊字符替换为相应的十六进制值。

三、iOS上URL的具体编码处理 1、URL编码和解码是成对出现的

URL编码和解码是一个可逆过程,编码和解码的逻辑是相反的。

配对有两层含义:

• 1、两种方法的逻辑对应关系。 固定的编码方法也对应于固定的逆解码方法,反之亦然。

• 2. 编码和解码时间也必须一一对应。

在这四个字符之后,URL 编码值仍然是其本身:

1. 英文字母(az AZ)

2. 数字(0-9)

3. 特殊字符(-_.)

4.一些保留字符(英文字符):! * '(); : @ & = + $ , / ?

注:~#【】这四个字符是否转码为百分号编码,根据系统不同会有所不同。

URL 字符编码使用 % 百分号加两个字符 – 表示字节的十六进制形式。 因为编码值包含%保留字符。 再次编译%以编译%25。

例如:&

第一个 URL 编码后:%26

第二次URL编码后:%2526

第三次URL编码后:%

正常解码逻辑:

第一次 URL 解码后:%2526

第二次 URL 解码后:%26

第三次URL解码后:&

因此,URL编码和解码必须成对发生。

初始字符为&,连续编码3次,解码2次,得到%26。

初始字符为&%26,编码一次:%26%2526,连续解码两次得到&&。

2. URL是如何分解的?

我们来看一个常见的接口请求示例:

一般将请求的协议、服务器名(或IP地址)、端口号、路径和文件名、参数名、参数值等按照://、:、/、?、&、=等进行分割。

3. URL编码是在组装URL的哪个阶段进行的?

我们来看一个常见的接口请求示例:

编码urf-8的不可映射字符_URL编码_编码url是什么意思

绿色字体是具有特殊含义的保留字符,不应进行编码。 红色字体部分必须编译。 不应编译具有黄色背景的字符串。 如果上述操作不正确,将会影响整个URL的解析。

常见的缝合工艺:

1、先拼接实际请求地址来测试?

2、然后拼接参数字符串wd=&&=

3. 将 1 和 2 组合成 URL 字符串。

4. 将 URL 字符串转换为 NSURL 实例。

分析

1、由于test@test包含中文和保留字符@,所以需要在步骤1之前将test@test编码为%e6%b5%8b%40%e8%af%95,然后拼接成%e6% b5%8b%40%e8%af%95?

2、由于搜索&中包含中文和保留字符&,&会影响参数解析。 需要先搜索编码%e6%90%9c%26%e7%b4%a2,然后拼接成wd=%e6%90%9c%26%e7%b4%a2&=

3、由于请求地址和参数列表已经编码完毕,拼接后的完整请求不需要重新编译。 如果再次编译,会被编译成x,因为它包含×。

概括

上面我们对特殊字符分别进行了编码,最后将它们拼接在一起。 还有一些写法是拼接后联合编码处理的。 但由于请求路径和请求参数中可能含有保留字符&、=、中文等特殊字符,导致请求地址解析错误。 建议在拼接路径和参数之前对路径、参数名、参数值进行统一编码,然后进行拼接。 拼接后不再编码,而是转换为NSURL实例并发送请求。

4. 可用的编解码API

URL编码是互联网的通用规范,各个系统或平台都会提供封装好的API方法供开发者调用。 iOS 端正在生成一个 NSURL 实例。

NSURL *url = [NSURL URLWithString:urlString];

特别需要注意的是,当存在中文字符之外的非限定URL限制字符时,创建的NSURL对象会失败,url会返回nil。

4.1. iOS 7之前的编解码处理

4.1.1. 方法一:g

字符串URL编码实现

NSString *urlStr = @"你好0123456789abcxyzABCXYZ-_.~&!*'();:@&=+$,/?#[] %25";
NSString *encodingString = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"url编码 = %@",encodingString);

注:最后一个是空格符号,下面用黄色背景标记。

打印结果是

字符串URL解码实现

请求返回的数据格式为%E4%BD%A0%E5%A5%BD,需要UTF-8解码。 对应的方法是:

NSString *encodingString = @"%E4%BD%A0%E5%A5%BD0123456789abcxyzABCXYZ-_.~&!*'();:@&=+$,/?%23%5B%5D%25%20";
NSString *decodedStr = [encodingString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"url解码 = %@",decodedStr);

打印结果是

通过上面的编码和解码过程,我们可以知道

[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

绿色字体YZ-_.~&!*'();:@&=+$,/? 这些字符不会被编译成%百分号编码,只有特殊的#、[、]、%、(空格)和汉字才会被编译。

概括

从第2章4.2节可以了解到,URL请求中可能存在特殊字符-_.~&!*'();:@&=+$,/?#[]%(最后一个是空格)如果在路径或参数表中不进行转义编码,很容易造成URL解析时出现歧义,导致解析错误、找不到指定资源、网络请求失败或出错。 该方法只能处理URL编码指定的字符集之外且不包含上述特殊字符的字符。 这种方法不适合URL的整体编译。 它可以部分编译没有特殊字符的URL部分。 它有太多的限制。 URL编解码中不建议使用该方法。 另外,苹果在iOS9之后也放弃了这种方法。

另外,还有一些方法,无法编译-_.~&!*'();:@&=+$,/?#[]%特殊字符。 处理结果与方法1基本相同,不再展开。 解释道。

4.1.2. 方法二:

字符串URL编码实现

NSString *urlStr = @"你好0123456789abcxyzABCXYZ-_.~&!*'();:@&=+$,/?#[]% ";
//方式一编码对比
NSString *encodingStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"url编码1-1 = %@",encodingStr);
//方式二编码定义空字符集
NSString *encodeStr = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)urlStr, NULL, (CFStringRef)@"", kCFStringEncodingUTF8));
NSLog(@"url编码2-1 = %@",encodeStr);
//方式二编码定义 ABC-_~.!*'();:@&=+ $,/?%#[] 字符集
NSString *encodeStr2 = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)urlStr, NULL, (CFStringRef)@"ABC-_~.!*'();:@&=+ $,/?%#[]", kCFStringEncodingUTF8));
NSLog(@"url编码2-2 = %@",encodeStr2);

注:最后一位是空格符号。 编码2-2强制编译自定义字符集ABC-_~.!*'();:@&=+ $,/?%#[]。 结果如下:

编码urf-8的不可映射字符_编码url是什么意思_URL编码

字符串URL解码实现

NSString *encodedString = @"%E4%BD%A0%E5%A5%BD0123456789abcxyz%41%42%43XYZ%2D%5F%2E%7E&%21%2A%27%28%29%3B%3A@&%3D%2B%24%2C%2F%3F%23%5B%5D%25%20";

NSString *decodedStr = (NSString *)CFBridgingRelease(CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault,(CFStringRef)encodedString,CFSTR(""),kCFStringEncodingUTF8));
NSLog(@"url解码2-1 = %@"
,decodedStr);


NSString *decodedStr2 = (NSString *)CFBridgingRelease(CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault,(CFStringRef)encodedString,CFSTR(";:@&"),kCFStringEncodingUTF8));
NSLog(@"url解码2-2 = %@",decodedStr);

打印结果是

编码urf-8的不可映射字符_编码url是什么意思_URL编码

概括

从上面的数据可以看出,方法2在方法1编码的基础上还可以对自定义特殊字符集进行编码,解决了方法1的问题。

解码2-2强制不解码自定义字符集ABC-_~.!*'();:@&=+ $,/?%#[],但仍然有两个字符@&是特殊的,被排除从解码来看除此之外,具体原因目前未知。

在iOS7之前,建议使用方法2,以确保自定义字符集能够完全覆盖可能存在歧义的字符。

该方法可以编译特殊字符。 因此,不适合对URL进行整体编译。 只能先编译各个URL部分,然后再将它们组装在一起。

4.2. iOS 7之后的编解码处理

4.2.1. 全新方式:

iOS9之后,苹果推荐使用新的方法。 其实iOS7之后就可以调用这个方法了。

Apple对此方法的注释:用百分比编码字符替换集合中未包含的所有字符,返回从接收器生成的新字符串。 UTF-8 编码用于确定编码字符的正确百分比。 整个 URL 字符串无法进行百分比编码。 此方法用于对 URL 组件或子组件字符串进行百分比编码,而不是对整个 URL 字符串进行百分比编码。 7 位 ascii 范围之外的允许字符中的任何字符都将被忽略。

字符串URL编码实现

NSString *urlStr = @"你好0123456789abcxyzABCXYZ-_.~&!*'();:@&=+$,/?#[]% ";
//方式一编码对比
NSString *encodingString = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"url编码1-1 = %@",encodingString);

//方式二自定义字符集 ABC-_~.!*'();:@&=+ $,/?%#[] 编码对比
NSString *encodeStr2 = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)urlStr, NULL, (CFStringRef)@"ABC-_~.!*'();:=+ $,/?%#[]", kCFStringEncodingUTF8));
NSLog(@"url编码2-2 = %@",encodeStr2);

//系统提供的枚举字符集,这些字符不需要 编译
NSString *encodeStr3 = [urlStr stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSLog(@"url编码3-1 = %@",encodeStr3);

//自定义字符不需要编译的字符集,为空字符集,将所有字符用百分号编码
NSCharacterSet *characterSet = [NSCharacterSet characterSetWithCharactersInString:@""];
NSString *encodeStr4 = [urlStr stringByAddingPercentEncodingWithAllowedCharacters:characterSet];
NSLog(@"url编码3-2 = %@",encodeStr4);

打印结果是

URL编码_编码urf-8的不可映射字符_编码url是什么意思

网上常见的字符集枚举说明(供参考):

URLFragmentAllowedCharacterSet  "#%[]^`{|}
URLHostAllowedCharacterSet      "
#%/?@^`{|}

URLPasswordAllowedCharacterSet  "#%/:?@[]^`{|}
URLPathAllowedCharacterSet      "
#%;?[]^`{|}

URLQueryAllowedCharacterSet     "#%[]^`{|}
URLUserAllowedCharacterSet      "
#%/:?@[]^`

字符串URL解码实现

//上段代码的结果为encodeStr3入参
NSString *decodedStr3 = [encodeStr3 stringByRemovingPercentEncoding];
NSLog(@"url编码3-1 = %@",decodedStr3);
//上段代码的结果为encodeStr4入参
NSString *decodedStr4 = [encodeStr4 stringByRemovingPercentEncoding];
NSLog(@"url编码3-2 = %@",decodedStr4);

打印结果是

解码接口统一,无需输入参数。

概括

我们知道,系统提供的URL特定编码url编码1-1和编码3-1并不能满足我们对常见请求示例进行正确编码和解码,如下所示:

因此需要根据业务定制字符集来定制URL编解码。 编码3-1使用系统字符集,系统不为打印字符集中的特定字符提供任何条目。 我们不能保证所有可能不明确的特殊字符都已进行转义编码。 建议我们使用URL编码3-2,自定义特殊字符甚至定义一个空字符集来编译所有本地字符,最后拼接成一个整体URL。

4.3. 最优解及包装加工

iOS7以下版本可以按照4.1.2的方式进行微调。 目前大部分APP都适配iOS7及以上版本,我们主要关注iOS7之后的解决方案。

创建一个+UTF_8类别,定义两个方法如下:

/**
对字符串的每个字符进行UTF-8编码

@return 百分号编码后的字符串
*/

- (NSString *)URLUTF8EncodingString
{
NSCharacterSet *characterSet = [NSCharacterSet characterSetWithCharactersInString:@""];
NSString *encodeStr = [self stringByAddingPercentEncodingWithAllowedCharacters:characterSet];
return encodeStr;
}
/**
对字符串的每个字符进行彻底的 UTF-8 解码
连续编码2次,需要连续解码2次,第三次继续解码时,则返回为空
@return 百分号编码解码后的字符串
*/

- (NSString *)URLUTF8DecodingString
{
NSString *decodedStr = [self stringByRemovingPercentEncoding];
while ([decodedStr stringByRemovingPercentEncoding] != nil) {
decodedStr = [decodedStr stringByRemovingPercentEncoding];
}
return decodedStr;
}

注意

g UTF-8编码可以无限制地多次调用。 该方法的特殊性在于字符串不是UTF-8编码格式,调用时返回nil,因此解码时只需要调用一次g即可完全UTF-8解码所有字符。 。

5、其他加工方法

需要编码的参数表可以整体封装为一个类型,也可以通过post请求发送。

四。 概括

1. 在进行URL组装和拼接之前,对字符串中所有可能引起歧义的部分进行完全UTF-8编码。

2、需要解码的地方,需要先对字符串进行分割,然后分段解码使用。

3.当组装好的数据需要重新组织时,需要先将其拆开,单独解码,然后编码,最后重新组装。

4. 服务器将对请求进行一次UTF-8解码。 请确保请求中的字符仅经过一次 UTF-8 编码。

参考

[1]

[2]

[3]

[4]

推荐↓↓↓

编码url是什么意思_URL编码_编码urf-8的不可映射字符

长的

根据

关闭

笔记

【】都在这儿了!

涵盖:大程序员、源码分享读、程序员分享读、数据结构与算法、黑客技术与网络安全、大数据技术、编程前端、Java、、Web编程开发、iOS开发、Linux、数据库开发、幽默程序员等

千山万水,爱情总在,你能点击“寻找”吗?

好了,今天的主题就讲到这里吧,不管如何,能帮到你我就很开心了,如果您觉得这篇文章写得不错,欢迎点赞和分享给身边的朋友。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注