首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用NSURLComponents将+编码为%2B

如何使用NSURLComponents将+编码为%2B
EN

Stack Overflow用户
提问于 2015-07-23 10:27:09
回答 4查看 5.7K关注 0票数 15

我使用的是NSURLComponents,但我似乎无法获得正确编码的查询值。我需要最终的网址表示为%2B+

代码语言:javascript
运行
复制
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")

失败!

输出等于:

代码语言:javascript
运行
复制
http://www.example.com?connectionToken=abc+def 

代码语言:javascript
运行
复制
http://www.example.com?connectionToken=abc%2Bdef

我尝试了几个变体,但似乎根本不能将其输出为%2B

EN

回答 4

Stack Overflow用户

发布于 2016-05-19 12:49:52

我的答案来自Radar 24076063,并解释了它为什么会这样工作(对文本进行了一些清理):

'+‘字符在查询组件中是合法的,因此不需要使用百分号编码。

某些系统使用'+‘作为空格,并要求'+’加号字符采用百分号编码。然而,这种两阶段编码(将加号转换为%2B,然后将空格转换为加号)容易出错,因为它很容易导致编码问题。如果URL是规范化的,它也会中断(URL的语法规范化包括删除所有不必要的百分比编码-参见rfc3986第6.2.2.2节)。

因此,如果因为您的代码与之对话的服务器而需要该行为,那么您将自己处理额外的转换。下面是一段代码,展示了两种方法都需要做的事情:

NSURLComponents *components = [NSURLComponents alloc ];NSArray *items = [NSArray arrayWithObjects:NSURLQueryItem queryItemWithName:@"name“value:@"Value +",nil];components.queryItems = items;NSLog(@"URL:%@",components queryItems);NSLog(@"URL:%@",components string);//将percentEncodedQuery中的所有"+“替换为"%2B”(百分比编码+),然后将所有"%20“(百分比编码空格)替换为"+”components.percentEncodedQuery = [components.percentEncodedQuery stringByReplacingOccurrencesOfString:@"+“withString:@"%2B”stringByReplacingOccurrencesOfString:@"%20“withString:@"+"];NSLog(@"URL string after:%@",components string);//如果您收到具有该形式的查询的URL,并希望使用queryItems components.percentEncodedQuery = [components.percentEncodedQuery stringByReplacingOccurrencesOfString:@"+“withString:@"%20”stringByReplacingOccurrencesOfString:@"%2B“withString:@"+"];NSLog(@"URL string back:%@",components string);NSLog(@"URL queryItems:%@",components queryItems);

输出为:

URL queryItems:( " {名称=名称,值=值+}“) URL字符串之前:?name=Value%20+ URL字符串之后:?name=Value+%2B URL字符串返回:?name=Value%20+ URL queryItems:( " {名称=名称,值=值+}”)

票数 24
EN

Stack Overflow用户

发布于 2017-06-23 20:18:42

正如其他答案所提到的,默认情况下"+“不是在iOS上编码的。但如果您的服务器需要对其进行编码,以下是如何进行编码的方法:

代码语言:javascript
运行
复制
var comps = URLComponents(url: self, resolvingAgainstBaseURL: true)
// a local var is needed to fix a swift warning about "overlapping accesses" caused by writing to the same property that's being read.
var compsCopy = comps
compsCopy?.queryItems = [URLQueryItem(name: "name", value: "abc+def")]
comps?.percentEncodedQuery = compsCopy?.percentEncodedQuery?.replacingOccurrences(of: "+", with: "%2B")
票数 11
EN

Stack Overflow用户

发布于 2017-04-29 18:23:44

当内容类型是application/x-www-form-urlencoded时,+可能是一个有效字符,请参见the link,因此NSURLComponents不会对其进行编码。

苹果还提到了this

URLRFC3986指定必须在

的查询组件中对哪些字符进行百分比编码,但不指定应如何解释这些字符。使用带分隔符的键值对是一种常见的约定,但规范并未对其进行标准化。因此,您可能会遇到与遵循此约定的其他实现的互操作性问题。

潜在互操作性问题的一个值得注意的示例是加号(+)字符的处理方式:

根据RFC3986,加号是查询中的有效字符,不需要进行百分号编码。但是,根据W3C对URI寻址的建议,加号是作为查询字符串(例如,?greeting=hello+world)中的空格的速记符号保留的。

如果URL查询组件包含根据RFC 3339格式化的日期,且时区偏移量中带有加号(例如,2013-12-31T14:00:00+00:00),则将加号解释为空格会导致时间格式无效。RFC3339指定应如何格式化日期,但不建议加号是否必须在URL中进行百分号编码。根据接收此URL的实现,您可能需要对加号字符进行抢占百分号编码。

另一种方法是,考虑以更健壮的数据交换格式(如JSON或XML )编码复杂和/或可能有问题的数据。

结论是你可能会也可能不会编码'+‘。

在我看来,NSURLComponents只编码它确定应该编码字符,如'&','=‘或像’你‘’好‘这样的汉字,它不编码字符可能根据内容类型编码或不编码,如我上面提到的'+’。因此,如果你发现你必须编码'+‘或者你的服务器不能正确解析,你可以使用下面的代码。

我不知道swift,所以我只提供了objective-c代码,很抱歉。

代码语言:javascript
运行
复制
- (NSString *)URLEncodingValue:(NSString *)value
{
    NSCharacterSet *set = [NSCharacterSet URLQueryAllowedCharacterSet];
    NSMutableCharacterSet *mutableQueryAllowedCharacterSet = [set mutableCopy];
    [mutableQueryAllowedCharacterSet removeCharactersInString:@"!*'();:@&=+$,/?%#[]"];
    return [value stringByAddingPercentEncodingWithAllowedCharacters:mutableQueryAllowedCharacterSet];
}

!*'();:@&=+$,/?%#[]是RFC3986中定义的保留字符,代码将对它们进行编码,它们都出现在value参数中,如果您只想编码'+',只需将!*'();:@&=+$,/?%#[]替换为+即可。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31577188

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档