4

iOS アプリでAFNetworkingを使用しています。リクエスト パラメータにパーセント記号が含まれている場合に発生する問題を発見しました。その後、エンコードは失敗します。メソッドAFURLEncodedStringFromStringWithEncodingは nil を返します。

このコードをテストしたところ、次のように出力されます(null)

NSLog(@"%@", AFURLEncodedStringFromStringWithEncoding(@"%", NSUTF8StringEncoding));

予想される出力は次のようになります%25。他の文字は問題なくエンコードできます。

メソッドは次のように定義されます。

NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSStringEncoding encoding) {
    static NSString * const kAFLegalCharactersToBeEscaped = @"?!@#$^&%*+,:;='\"`<>()[]{}/\\|~ ";

    // Following the suggestion in documentation for `CFURLCreateStringByAddingPercentEscapes` to "pre-process" URL strings (using stringByReplacingPercentEscapesUsingEncoding) with unpredictable sequences that may already contain percent escapes.
    return [(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)[string stringByReplacingPercentEscapesUsingEncoding:encoding], NULL, (CFStringRef)kAFLegalCharactersToBeEscaped, CFStringConvertNSStringEncodingToEncoding(encoding)) autorelease];
}

ここで何がうまくいかないのですか?

編集: この問題は AFNetworking で修正されました。

4

2 に答える 2

1

APIについてはわかりませんが、URLエンコードは通常

  • 文字列部分(パス、引数など)をバイトにエンコードするUTF-8
  • バイト値のパーセントエンコードを適用して、ASCIIのみの文字列部分を取得します
  • 区切り文字:、/、?、&などを使用してURLピースをアセンブルします。
  • その文字列を再びバイトにエンコードする
  • 有線で送信

ニュアンスについては、 https://www.rfc-editor.org/rfc/rfc3986#section-2.5を参照してください。RFCは、URLがEBCDICシステム上のドキュメントを参照している場合、URLは、EBCDICシステムの人間のユーザーが知っている文字列名ではなく、その名前のEBCDICエンコーディングのバイト値を指定する必要があると述べていることに注意してください。したがって、URLは最終的には文字列ではなくバイト文字列になります。

APIでそのバイト文字列を正しく表現する方法については、よくわかりません。

于 2012-01-25T16:30:05.820 に答える
0

Just removing the stringByReplacingPercentEscapesUsingEncoding:encoding is fine, no need to encode twice, so the return value should be:

return [(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, 
                    (CFStringRef)string, 
                    NULL, 
                    (CFStringRef)kAFLegalCharactersToBeEscaped, 
                    CFStringConvertNSStringEncodingToEncoding(encoding)) autorelease];
于 2012-03-16T09:01:03.233 に答える