11

我需要在 GET 请求中传递带有时区偏移量的时间戳,例如,

2009-05-04T11:22:00+01:00

这看起来像是接收 PHP 脚本的两个参数“2009-05-04T11:22:00”和“01:00”(我无法控制)。

NSURL 不编码加号,但如果我使用字符串创建 NSURL

2009-05-04T11:22:00%2B01:00

我最终得到的网址包含:

2009-05-04T11:22:00%252B01:00

有什么想法可以保留我编码的加号或只是简单地阻止 NSURL 编码任何东西?

4

7 回答 7

13

对我有用的是进行 UTF8 转换,然后用 %2B 替换 + 符号:

NSString *urlString =
    [NSString stringWithFormat:@"%@/iphone/push/create?pn[token]=%@&pn[send_at]=%@",
     kHTTPURL, appDelegate.deviceAPNToken, [dateTimeToUse description]];

urlString =
    [[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]
     stringByReplacingOccurrencesOfString:@"+" withString:@"%2B"];
于 2010-02-15T22:00:28.350 回答
3

字符串应该是 URL 编码的。

这是 NSString 的一个类别,它会有所帮助:

NSString+Additions.h

@interface NSString (Additions)

- (NSString *)stringByURLEncoding;

NSString+Additions.m

#import "NSString+Additions.h"

@implementation NSString (Additions)

- (NSString *)stringByURLEncoding {
    return (__bridge NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
                                                           (CFStringRef)self,
                                                           NULL,
                                                           (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
                                                           CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));
}
于 2013-06-18T05:22:20.977 回答
2

在要作为参数包含的文本上使用NSString'方法。stringByAddingPercentEscapesUsingEncoding:

顾名思义,该方法将转换返回一个自动发布的字符串,其中包含接收器的 url 安全版本。

于 2009-05-22T16:39:41.853 回答
2

认为我不妨提供我的解决方法作为答案,因为我认为原始问题没有很好的解决方案。

加号 (+) 在 URL 中完全有效,因此我的解决方案是将时间转换为 GMT 并从字符串中删除时区/DST 偏移量。我将把它作为练习留给读者来确定下面secondsFromGMT的值,因为在我的情况下,它总是相同的,因为我只对 Web 服务器生成的时间戳感兴趣。

NSString *gmtWhen = [[self descriptionWithCalendarFormat:nil
                           timeZone:[NSTimeZone
                           timeZoneForSecondsFromGMT:secondsFromGMT
                     ] locale:nil] stringByReplacingOccurrencesOfString:@" +0000" withString:@""];
于 2009-05-23T07:38:23.057 回答
1

使用URLComponents (Swift 3) 时的解决方案:

var params = ["email": "user+ios-default@example.com", "name": "John Brown"]
var components = URLComponents(string: "http://www.example.com")!
components.path = "/login"
components.queryItems = params.map { URLQueryItem(name: $0, value: $1) }

let url_NoFix = components.url!
// http://www.example.com/login?name=John%20Brown&email=user+ios-default@example.com

let cs = CharacterSet(charactersIn: "+").inverted
let q =  components.percentEncodedQuery?.addingPercentEncoding(withAllowedCharacters: cs)
components.percentEncodedQuery = q

let url_Fixed = components.url!
// http://www.example.com/login?name=John%20Brown&email=user%2Bios-default@example.com
于 2016-11-06T01:12:08.143 回答
0

使用以下代码对字符串进行编码

NSString *result = (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)self,NULL,(CFStringRef)@"+",kCFStringEncodingUTF8);

这将对你的字符串进行编码,这将防止在 post 方法中发布数据时将 + 替换为 %2b

于 2014-10-01T06:56:43.837 回答
0

要获得编码加 (%2B)(它适用于所有字符),请使用CFURLCreateStringByAddingPercentEscapes as

/**
 get parameterized url from url and query parameters.
 */
+(NSString *)getParameterizedUrl:(NSString *)url withParameters:(NSDictionary *)queryDictionary
{
    NSMutableArray *mutablePairs = [NSMutableArray array];
    for (NSString *key in queryDictionary) {
        [mutablePairs addObject:[NSString stringWithFormat:@"%@=%@", CTPercentEscapedQueryStringKeyFromStringWithEncoding(key, NSUTF8StringEncoding), CTPercentEscapedQueryStringValueFromStringWithEncoding(queryDictionary[key], NSUTF8StringEncoding)]];
    }

    return [[NSString alloc]initWithFormat:@"%@?%@",url,[mutablePairs componentsJoinedByString:@"&"]];
}

static NSString * const kCharactersToBeEscapedInQueryString = @":/?&=;+!@#$()',*";

static NSString * CTPercentEscapedQueryStringKeyFromStringWithEncoding(NSString *string, NSStringEncoding encoding) {
    static NSString * const kCharactersToLeaveUnescapedInQueryStringPairKey = @"[].";

    return (__bridge_transfer  NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, (__bridge CFStringRef)kCharactersToLeaveUnescapedInQueryStringPairKey, (__bridge CFStringRef)kCharactersToBeEscapedInQueryString, CFStringConvertNSStringEncodingToEncoding(encoding));
}

static NSString * CTPercentEscapedQueryStringValueFromStringWithEncoding(NSString *string, NSStringEncoding encoding) {
    return (__bridge_transfer  NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, NULL, (__bridge CFStringRef)kCharactersToBeEscapedInQueryString, CFStringConvertNSStringEncodingToEncoding(encoding));
}

并在您的代码中使用

NSMutableDictionary *params = [[NSMutableDictionary alloc]init];
[params setObject:@"2009-05-04T11:22:00+01:00" forKey:@"timestamp"];

NSString *urlString = [self getParameterizedUrl:@"http://www.example.com" withParameters:params];
NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
于 2015-06-29T10:50:20.920 回答