7

このコード スニペットが機能していません。「認証に失敗しました」というメッセージが表示されます。サーバーからの応答。何か案は?

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] 
                                    initWithURL:
                                    [NSURL URLWithString:@"http://www.tumblr.com/api/write"]];
    [request setHTTPMethod:@"POST"];
    [request addValue:_tumblrLogin forHTTPHeaderField:@"email"];
    [request addValue:_tumblrPassword forHTTPHeaderField:@"password"];
    [request addValue:@"regular" forHTTPHeaderField:@"type"];
    [request addValue:@"theTitle" forHTTPHeaderField:@"title"];
    [request addValue:@"theBody" forHTTPHeaderField:@"body"];

    NSLog(@"Tumblr Login:%@\nTumblr Password:%@", _tumblrLogin, _tumblrPassword);

    [NSURLConnection connectionWithRequest:request delegate:self];

    [request release];

_tumblrLoginとの両方_tumblrPasswordが、コードの他の場所で実行さstringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncodingれます。私のログイン電子メールは、「address+test@test.com」の形式です。tumblr に直接ログインする場合は問題なく動作しますが、「+」文字がエンコードに問題を引き起こしているのではないでしょうか? 逃げられているわけではありません。それはすべきですか?


Martin の提案のおかげでCFURLCreateStringByAddingPercentEscapes、ログインとパスワードをエスケープするために使用しています。私はまだ同じ問題を抱えていますが、私の認証は失敗しています。

4

2 に答える 2

22

問題は、適切な HTTP POST 要求を作成していないことです。POST 要求には、サーバーに送信するすべてのパラメーターを含む、適切にフォーマットされたマルチパート MIME エンコードされた本文が必要です。まったく機能しない HTTP ヘッダーとしてパラメータを設定しようとしています。

このコードはあなたが望むことを行います。特に、NSString有効なマルチパート MIME 文字列を作成するカテゴリに注意してください。

@interface NSString (MIMEAdditions)
+ (NSString*)MIMEBoundary;
+ (NSString*)multipartMIMEStringWithDictionary:(NSDictionary*)dict;
@end

@implementation NSString (MIMEAdditions)
//this returns a unique boundary which is used in constructing the multipart MIME body of the POST request
+ (NSString*)MIMEBoundary
{
    static NSString* MIMEBoundary = nil;
    if(!MIMEBoundary)
        MIMEBoundary = [[NSString alloc] initWithFormat:@"----_=_YourAppNameNoSpaces_%@_=_----",[[NSProcessInfo processInfo] globallyUniqueString]];
    return MIMEBoundary;
}
//this create a correctly structured multipart MIME body for the POST request from a dictionary
+ (NSString*)multipartMIMEStringWithDictionary:(NSDictionary*)dict 
{
    NSMutableString* result = [NSMutableString string];
    for (NSString* key in dict)
    {
        [result appendFormat:@"--%@\r\nContent-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n",[NSString MIMEBoundary],key,[dict objectForKey:key]];
    }
    [result appendFormat:@"\r\n--%@--\r\n",[NSString MIMEBoundary]];
    return result;
}
@end


@implementation YourObject
- (void)postToTumblr
{
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] 
                                    initWithURL:
                                    [NSURL URLWithString:@"http://www.tumblr.com/api/write"]];
    [request setHTTPMethod:@"POST"];
    //tell the server to expect 8-bit encoded content as we're sending UTF-8 data, 
    //and UTF-8 is an 8-bit encoding
    [request addValue:@"8bit" forHTTPHeaderField:@"Content-Transfer-Encoding"];
    //set the content-type header to multipart MIME
    [request addValue: [NSString stringWithFormat:@"multipart/form-data; boundary=%@",[NSString MIMEBoundary]] forHTTPHeaderField: @"Content-Type"];

    //create a dictionary for all the fields you want to send in the POST request
    NSDictionary* postData = [NSDictionary dictionaryWithObjectsAndKeys:
                                 _tumblrLogin, @"email",
                                 _tumblrPassword, @"password",
                                 @"regular", @"type",
                                 @"theTitle", @"title",
                                 @"theBody", @"body",
                                 nil];
    //set the body of the POST request to the multipart MIME encoded dictionary
    [request setHTTPBody: [[NSString multipartMIMEStringWithDictionary: postData] dataUsingEncoding: NSUTF8StringEncoding]];
    NSLog(@"Tumblr Login:%@\nTumblr Password:%@", _tumblrLogin, _tumblrPassword);
    [NSURLConnection connectionWithRequest:request delegate:self];
    [request release];
}
@end
于 2010-02-24T22:47:15.727 に答える
0

この質問への回答によるとstringByAddingPercentEscapesUsingEncoding:、完全なエスケープエンコーディングを実行しません。ただし、何らかの理由で、このメソッドのCoreFoundationバージョンは次のことを行います。

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

NSMutableStringのreplaceOccurencesOfString:withString:options:メソッドを使用して手動で置換を行うこともできますが、そのメソッドはより反復的で冗長です。(ここを参照してください。)

于 2010-02-24T14:59:30.187 に答える