Objective C HTML escape / unescape

Objective C'de basit bir HTML escape/unescape yapmanın kolay bir yolu olup olmadığını merak ediyorum. istediğim bu psuedo kodu gibi bir şey:

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

döndüren

<span>Foo</span>

umarım ☆ ve benzeri gibi tüm diğer HTML varlıkları yanı sıra ve hatta ASCII kodları unescaping.

bunu yapmak için Touch / Uıkit'te herhangi bir yöntem var mı?

72
tarihinde sordu Peter Hosey 2009-03-18 21:43:23
kaynak

14 ответов

bu bağlantı aşağıdaki çözümü içerir. Kakao CF CFXMLCreateStringByUnescapingEntities işlevi vardır ama bu iPhone'da kullanılamaz.

@interface MREntitiesConverter : NSObject <NSXMLParserDelegate>{
    NSMutableString* resultString;
}

@property (nonatomic, retain) NSMutableString* resultString;

- (NSString*)convertEntitiesInString:(NSString*)s;

@end


@implementation MREntitiesConverter

@synthesize resultString;

- (id)init
{
    if([super init]) {
        resultString = [[NSMutableString alloc] init];
    }
    return self;
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)s {
        [self.resultString appendString:s];
}

- (NSString*)convertEntitiesInString:(NSString*)s {
    if (!s) {
        NSLog(@"ERROR : Parameter string is nil");
    }
    NSString* xmlStr = [NSString stringWithFormat:@"<d>%@</d>", s];
    NSData *data = [xmlStr dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
    NSXMLParser* xmlParse = [[[NSXMLParser alloc] initWithData:data] autorelease];
    [xmlParse setDelegate:self];
    [xmlParse parse];
    return [NSString stringWithFormat:@"%@",resultString];
}

- (void)dealloc {
    [resultString release];
    [super dealloc];
}

@end
30
cevap Andrew Grant 2014-06-10 19:55:44
kaynak

check out my Nsstring Category for XMLEntities . XML varlıklarını (tüm HTML karakter referansları dahil) kodlamak, XML varlıklarını kodlamak, etiketleri sıyırmak ve bir dizeden yeni satır ve boşluk kaldırmak için yöntemler vardır:

- (NSString *)stringByStrippingTags;
- (NSString *)stringByDecodingXMLEntities; // Including all HTML character references
- (NSString *)stringByEncodingXMLEntities;
- (NSString *)stringWithNewLinesAsBRs;
- (NSString *)stringByRemovingNewLinesAndWhitespace;
90
cevap Michael Waterfall 2013-08-05 13:48:33
kaynak

başka bir HTML NSString kategorisi Google Toolbox for Mac

İsme rağmen, bu da ios'ta çalışıyor.

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;

ve projeye sadece üç dosya eklemek zorunda kaldım: başlık, uygulama ve GTMDefines.h .

34
cevap Nikita Rybak 2011-03-02 08:48:47
kaynak

bu yaptığım inanılmaz bir araya getirilmiş bir çözümdür, ancak ayrıştırma konusunda endişelenmeden bir dizeden kaçmak istiyorsanız, bunu yapın:

-(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;
    }

hiçbir şekilde zarif olmadığını biliyorum, ama işi hallediyor. Daha sonra bir öğeyi arayarak çözebilirsiniz:

string = [self htmlEntityDecode:string];

dediğim gibi, hacky ama işe yarıyor. Bir dize kodlamak istiyorsanız, sadece ters stringByReplacingOccurencesOfString parametreleri.

28
cevap Andrew Kozlik 2015-12-17 04:13:33
kaynak

iOS 7'de NSATTRİBUTEDSTRİNG'İN HTML varlıklarını bir Nsstring'e dönüştürmek için HTML'yi içe aktarma yeteneğini kullanabilirsiniz.

Eg:

@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

varlıkları temizlemek istediğinizde kodunuzda:

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

Bu muhtemelen en basit yoldur, ancak ne kadar performant olduğunu bilmiyorum. Muhtemelen "temizlik" içeriğinizin <img> etiketlerini veya bunun gibi şeyleri içermediğinden oldukça emin olmalısınız bu yöntem HTML sırasında bu görüntüleri indirmek çünkü NSAttributedString dönüştürme. :)

11
cevap orj 2014-02-20 11:30:50
kaynak

işte tüm karakterleri nötralize eden bir çözüm (bunları unicode değeri için tüm HTML kodlanmış varlıkları yaparak)... Bunu benim ihtiyaçlarım için kullandım (kullanıcıdan gelen ancak bir webview'in içine yerleştirilmiş bir dize herhangi bir XSS saldırısı olamazdı):

arayüz:

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

uygulama:

@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

Kullanım Örneği:

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

kilometre değişecektir.

5
cevap BadPirate 2013-02-04 22:20:52
kaynak

kodlamak ve HTML veya XML dizeleri kodlamak için en az invaziv ve en hafif yolu Gtmnsstringhtmladd CocoaPod kullanmaktır .

sadece GTMDefines.h bağımlılığı elimden Mac NSString kategori GTMNSString+HTML için Google Toolbox olduğunu . Yani eklemeniz gereken tek şey bir .H ve bir .m, sen de gitmekte iyisin.

örnek:

#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>
4
cevap T Blank 2015-09-09 19:44:04
kaynak

bu NSString kategori uygulaması kullanımı kolaydır:

tamamlamadan uzaktır, ancak buradan bazı eksik varlıklar ekleyebilirsiniz: http://code.google.com/p/statz/source/browse/trunk/NSString%2BHTML.m

kullanımı:

#import "NSString+HTML.h"

NSString *raw = [NSString stringWithFormat:@"<div></div>"];
NSString *escaped = [raw htmlEscapedString];
2
cevap Blago 2010-05-31 22:11:56
kaynak

yukarıdaki MREntitiesConverter, kodlayıcı değil, bir HTML striptizcisidir.

bir kodlayıcıya ihtiyacınız varsa, buraya gidin: XML/HTML için Nsstring'i kodlayın

1
cevap Brain2000 2017-05-23 15:03:06
kaynak

MREntitiesConverter hatalı biçimlendirilmiş xml kaçmak için çalışmıyor. Basit bir URL'de başarısız olur:

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

0
cevap richcollins 2009-09-21 05:50:05
kaynak

bir literal oluşturmanız gerekiyorsa, aşağıdaki gibi bir araç kullanmayı düşünebilirsiniz:

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

sizin için işi gerçekleştirmek için.

Ayrıca bakınız bu cevap .

0
cevap diadyne 2017-05-23 15:26:23
kaynak

bu en kolay çözüm aşağıdaki gibi bir kategori oluşturmaktır:

İşte kategorinin başlık dosyası:

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

ve işte uygulama:

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

ve şimdi bunu yapabiliriz:

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

bu cevap için kredi aşağıdaki Web sitesine gider: -

http://madebymany.com/blog/url-encoding-an-nsstring-on-ios
0
cevap Hashim Akhtar 2015-02-11 19:28:08
kaynak

neden sadece kullanmıyor ?

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

Noob sorusu ama benim durumumda işe yarıyor...

-4
cevap iwalktheline 2011-02-18 13:21:55
kaynak

bu, birkaç yıl önce yayınladığım eski bir cevap. Niyetim ... bir şey düzgün çalışmıyor ve ne olduğundan emin değiliz. bu bazı şartlar altında yararlı olabilir. Başka bir şey işe yaramazsa lütfen bu çözümü kullanmayın.

aslında, diğer birçok durumda mükemmel çalışıyor cevaplar değil çünkü Uıwebview tüm işi yapıyor. Ve hatta bazı javascript enjekte (hangi olabilir tehlikeli ve/veya yararlı). Performans korkunç olmalı, ama aslında o kadar da kötü değil.

belirtilmesi gereken başka bir çözüm var. Sadece UIWebView oluşturun , kodlanmış dizeyi yükleyin ve metni geri alın. "<>"Etiketlerinden kaçar ve ayrıca tüm html varlıkları (örneğin">") çözer ve diğerlerinin (örneğin kirilikler kullanarak) olmadığı yerlerde çalışabilir. Bunun en iyi çözüm olduğunu düşünmüyorum, ancak yukarıdaki çözümler işe yaramazsa yararlı olabilir.

işte ARC kullanarak küçük bir örnek:

@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
-5
cevap FranMowinckel 2015-04-10 16:43:00
kaynak