74

Objective C で単純な HTML エスケープ/エスケープを行う簡単な方法があるかどうか疑問に思っています。私が欲しいのは、次の疑似コードのようなものです。

NSString *string = @"<span>Foo</span>";
[string stringByUnescapingHTML];

どちらが返されますか

<span>Foo</span>

うまくいけば、他のすべての HTML エンティティもエスケープ解除されます。また、oe などの ASCII コードもエスケープ解除されます。

これを行うための Cocoa Touch/UIKit のメソッドはありますか?

4

14 に答える 14

91

XMLEntities の NSString カテゴリをチェックしてください。XML エンティティ (すべての HTML 文字参照を含む) のデコード、XML エンティティのエンコード、タグの削除、文字列からの改行と空白の削除を行うメソッドがあります。

- (NSString *)stringByStrippingTags;
- (NSString *)stringByDecodingXMLEntities; // Including all HTML character references
- (NSString *)stringByEncodingXMLEntities;
- (NSString *)stringWithNewLinesAsBRs;
- (NSString *)stringByRemovingNewLinesAndWhitespace;
于 2010-05-16T11:02:03.357 に答える
35

Google Toolbox for Macの別の HTML NSString カテゴリ
名前にもかかわらず、これは iOS でも機能します。

http://google-toolbox-for-mac.googlecode.com/svn/trunk/Foundation/GTMNSString+HTML.h

/// Get a string where internal characters that are escaped for HTML are unescaped 
//
///  For example, '&amp;' becomes '&'
///  Handles &#32; and &#x32; cases as well
///
//  Returns:
//    Autoreleased NSString
//
- (NSString *)gtm_stringByUnescapingFromHTML;

そして、プロジェクトに含める必要があったのは、ヘッダー、実装、GTMDefines.h.

于 2011-03-02T05:48:47.897 に答える
29

これは私が行った非常にハックされたソリューションですが、解析を気にせずに文字列を単純にエスケープしたい場合は、次のようにします。

-(NSString *)htmlEntityDecode:(NSString *)string
    {
        string = [string stringByReplacingOccurrencesOfString:@"&quot;" withString:@"\""];
        string = [string stringByReplacingOccurrencesOfString:@"&apos;" withString:@"'"];
        string = [string stringByReplacingOccurrencesOfString:@"&lt;" withString:@"<"];
        string = [string stringByReplacingOccurrencesOfString:@"&gt;" withString:@">"];
        string = [string stringByReplacingOccurrencesOfString:@"&amp;" withString:@"&"]; // Do this last so that, e.g. @"&amp;lt;" goes to @"&lt;" not @"<"

        return string;
    }

決してエレガントではないことはわかっていますが、仕事は完了します。次に、次を呼び出して要素をデコードできます。

string = [self htmlEntityDecode:string];

私が言ったように、それはハックですが、うまくいきます。文字列をエンコードする場合は、stringByReplaceingOccurencesOfString パラメータを逆にするだけです。

于 2010-09-16T15:50:05.660 に答える
11

iOS 7 では、NSAttributedString の HTML をインポートする機能を使用して、HTML エンティティを NSString に変換できます。

例えば:

@interface NSAttributedString (HTML)
+ (instancetype)attributedStringWithHTMLString:(NSString *)htmlString;
@end

@implementation NSAttributedString (HTML)
+ (instancetype)attributedStringWithHTMLString:(NSString *)htmlString
{
    NSDictionary *options = @{ NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType,
                               NSCharacterEncodingDocumentAttribute :@(NSUTF8StringEncoding) };

    NSData *data = [htmlString dataUsingEncoding:NSUTF8StringEncoding];

    return [[NSAttributedString alloc] initWithData:data options:options documentAttributes:nil error:nil];
}

@end

エンティティをクリーンアップする場合は、コードで次のようにします。

NSString *cleanString = [[NSAttributedString attributedStringWithHTMLString:question.title] string];

これはおそらく最も簡単な方法ですが、パフォーマンスがどの程度かはわかりません。<img>このメソッドは、HTML から NSAttributedString への変換中にこれらの画像をダウンロードするため、「クリーニング」のコンテンツにタグやそのようなものが含まれていないことを確認する必要があります。:)

于 2014-02-20T07:30:50.290 に答える
5

これは、すべての文字を中和するソリューションです(ユニコード値のすべての HTML エンコードされたエンティティにすることにより)...これを必要に応じて使用しました(ユーザーから取得した文字列が webview 内に配置されていないことを確認します) XSS 攻撃):

インターフェース:

@interface NSString (escape)
- (NSString*)stringByEncodingHTMLEntities;
@end

実装:

@implementation NSString (escape)

- (NSString*)stringByEncodingHTMLEntities {
    // Rather then mapping each individual entity and checking if it needs to be replaced, we simply replace every character with the hex entity

    NSMutableString *resultString = [NSMutableString string];
    for(int pos = 0; pos<[self length]; pos++)
        [resultString appendFormat:@"&#x%x;",[self characterAtIndex:pos]];
    return [NSString stringWithString:resultString];
}

@end

使用例:

UIWebView *webView = [[UIWebView alloc] init];
NSString *userInput = @"<script>alert('This is an XSS ATTACK!');</script>";
NSString *safeInput = [userInput stringByEncodingHTMLEntities];
[webView loadHTMLString:safeInput baseURL:nil];

あなたの走行距離は異なります。

于 2013-01-05T02:04:46.467 に答える
4

HTML または XML 文字列をエンコードおよびデコードする最も侵襲的で軽量な方法は、GTMNSStringHTMLAdditions CocoaPodを使用することです。

これは単に Google Toolbox for Mac の NSString カテゴリGTMNSString+HTMLであり、 への依存関係が取り除かれていGTMDefines.hます。したがって、追加する必要があるのは 1 つの .h と 1 つの .m だけで、準備完了です。

例:

#import "GTMNSString+HTML.h"

// Encoding a string with XML / HTML elements
NSString *stringToEncode = @"<TheBeat>Goes On</TheBeat>";
NSString *encodedString = [stringToEncode gtm_stringByEscapingForHTML];

// encodedString looks like this now:
// &lt;TheBeat&gt;Goes On&lt;/TheBeat&gt;

// Decoding a string with XML / HTML encoded elements
NSString *stringToDecode = @"&lt;TheBeat&gt;Goes On&lt;/TheBeat&gt;";
NSString *decodedString = [stringToDecode gtm_stringByUnescapingFromHTML];

// decodedString looks like this now:
// <TheBeat>Goes On</TheBeat>
于 2015-09-09T16:44:04.153 に答える
2

これは、使いやすい NSString カテゴリの実装です。

完全にはほど遠いですが、ここから不足しているエンティティを追加できます: http://code.google.com/p/statz/source/browse/trunk/NSString%2BHTML.m

使用法:

#import "NSString+HTML.h"

NSString *raw = [NSString stringWithFormat:@"<div></div>"];
NSString *escaped = [raw htmlEscapedString];
于 2010-05-31T18:00:28.330 に答える
1

上記の MREntitiesConverter は HTML ストリッパーであり、エンコーダーではありません。

エンコーダーが必要な場合は、ここにアクセスしてください: Encode NSString for XML/HTML

于 2009-12-19T05:12:52.737 に答える
0

リテラルを生成する必要がある場合は、次のようなツールの使用を検討してください。

http://www.freeformatter.com/java-dotnet-escape.html#ad-output

あなたのために仕事を成し遂げるために。

この回答も参照してください。

于 2014-02-26T19:09:00.667 に答える
0

MREntitiesConverter は、不正な形式の xml をエスケープするために機能しません。単純な URL では失敗します。

http://www.google.com/search?client=safari&rls=en&q=fail&ie=UTF-8&oe=UTF-8

于 2009-09-21T01:50:05.820 に答える
0

この最も簡単な解決策は、以下のようにカテゴリを作成することです。

カテゴリのヘッダー ファイルは次のとおりです。

#import <Foundation/Foundation.h>
@interface NSString (URLEncoding)
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding;
@end

そして、実装は次のとおりです。

#import "NSString+URLEncoding.h"
@implementation NSString (URLEncoding)
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding {
    return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
               (CFStringRef)self,
               NULL,
               (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
               CFStringConvertNSStringEncodingToEncoding(encoding));
}
@end

そして今、これを簡単に行うことができます:

NSString *raw = @"hell & brimstone + earthly/delight";
NSString *url = [NSString stringWithFormat:@"http://example.com/example?param=%@",
            [raw urlEncodeUsingEncoding:NSUTF8Encoding]];
NSLog(url);

この回答のクレジットは、以下の Web サイトに記載されています。

http://madebymany.com/blog/url-encoding-an-nsstring-on-ios
于 2015-02-11T16:28:08.363 に答える
-4

なぜ使用しないのですか?

NSData *data = [s dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
NSString *result = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
return result;

Noobの質問ですが、私の場合はうまくいきます...

于 2011-02-18T10:21:55.797 に答える
-5

これは私が数年前に投稿した古い回答です。私の意図は、「良い」「立派な」解決策を提供することではなく、状況によっては役立つかもしれない「ハッキーな」解決策を提供することでした。他に何も機能しない場合を除き、このソリューションを使用しないでください。

実際、UIWebViewがすべての作業を行っているため、他の回答では機能しない多くの状況で完全に機能します。また、javascript を注入することもできます (これは危険または有用な場合があります)。パフォーマンスはひどいはずですが、実際にはそれほど悪くはありません。

言及しなければならない別の解決策があります。を作成しUIWebView、エンコードされた文字列をロードして、テキストを取得するだけです。タグ "<>" をエスケープし、すべての html エンティティ (">" など) をデコードし、他のエンティティが機能しない場所 (キリル文字の使用など) で機能する可能性があります。これが最善の解決策だとは思いませんが、上記の解決策がうまくいかない場合に役立ちます。

ARC を使用した小さな例を次に示します。

@interface YourClass() <UIWebViewDelegate>

    @property UIWebView *webView;

@end

@implementation YourClass 

- (void)someMethodWhereYouGetTheHtmlString:(NSString *)htmlString {
    self.webView = [[UIWebView alloc] init];
    NSString *htmlString = [NSString stringWithFormat:@"<html><body>%@</body></html>", self.description];
    [self.webView loadHTMLString:htmlString baseURL:nil];
    self.webView.delegate = self;
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
    self.webView = nil;
}

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    self.webView = nil;
    NSString *escapedString = [self.webView stringByEvaluatingJavaScriptFromString:@"document.body.textContent;"];
}

- (void)webViewDidStartLoad:(UIWebView *)webView {
    // Do Nothing
}

@end
于 2013-09-08T19:13:56.250 に答える