Цель C HTML escape / unescape
интересно, есть ли простой способ сделать простой HTML escape/unescape в Objective C. Что я хочу, это что-то вроде этого кода psuedo:
NSString *string = @"<span>Foo</span>";
[string stringByUnescapingHTML];
возвращает
<span>Foo</span>
надеюсь, unescaping все другие HTML-объекты, а также и даже ASCII-коды, такие как Ӓ и тому подобное.
есть ли какие-либо методы в Cocoa Touch/UIKit для этого?
14 ответов:
этой ссылке содержит Решение ниже. Cocoa CF имеет функцию CFXMLCreateStringByUnescapingEntities, но она недоступна на iPhone.
@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
проверьте мои категория NSString для XMLEntities. Существуют методы для декодирования XML-объектов (включая все ссылки на символы HTML), кодирования XML-объектов, удаления тегов и удаления новых строк и пробелов из строки:
- (NSString *)stringByStrippingTags; - (NSString *)stringByDecodingXMLEntities; // Including all HTML character references - (NSString *)stringByEncodingXMLEntities; - (NSString *)stringWithNewLinesAsBRs; - (NSString *)stringByRemovingNewLinesAndWhitespace;
еще одна категория HTML NSString от Google Toolbox для Mac
Несмотря на название, это работает и на 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, '&' becomes '&' /// Handles   and 2 cases as well /// // Returns: // Autoreleased NSString // - (NSString *)gtm_stringByUnescapingFromHTML;и мне пришлось включить только три файла в проект: заголовок, реализация и
GTMDefines.h.
Это невероятно взломанное решение, которое я сделал, но если вы хотите просто избежать строки, не беспокоясь о разборе, сделайте это:
-(NSString *)htmlEntityDecode:(NSString *)string { string = [string stringByReplacingOccurrencesOfString:@""" withString:@"\""]; string = [string stringByReplacingOccurrencesOfString:@"'" withString:@"'"]; string = [string stringByReplacingOccurrencesOfString:@"<" withString:@"<"]; string = [string stringByReplacingOccurrencesOfString:@">" withString:@">"]; string = [string stringByReplacingOccurrencesOfString:@"&" withString:@"&"]; // Do this last so that, e.g. @"&lt;" goes to @"<" not @"<" return string; }Я знаю, что это не элегантный, но он получает работу. Затем вы можете декодировать элемент, вызвав:
string = [self htmlEntityDecode:string];Как я уже сказал, это хаки, но это работает. Если вы хотите закодировать строку, просто измените параметры stringByReplacingOccurencesOfString.
в 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. :)
вот решение, которое нейтрализует все символы (делая их все HTML-кодированные сущности для их значения unicode)... Использовал это для моей потребности (убедившись, что строка, которая пришла от пользователя, но была помещена внутри 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];ваш пробег будет меняться.
наименее инвазивный и самый легкий способ кодирования и декодирования строк HTML или XML-это использовать GTMNSStringHTMLAdditions CocoaPod.
это просто Google Toolbox для Mac NSString категории
GTMNSString+HTML, лишенный зависимости отGTMDefines.h. Так что все, что вам нужно добавить, это один .ч и одна .м, и ты можешь идти.пример:
#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: // <TheBeat>Goes On</TheBeat> // Decoding a string with XML / HTML encoded elements NSString *stringToDecode = @"<TheBeat>Goes On</TheBeat>"; NSString *decodedString = [stringToDecode gtm_stringByUnescapingFromHTML]; // decodedString looks like this now: // <TheBeat>Goes On</TheBeat>
это простая в использовании реализация категории NSString:
- http://code.google.com/p/qrcode-scanner-live/source/browse/trunk/iphone/Classes/NSString%2BHTML.h
- http://code.google.com/p/qrcode-scanner-live/source/browse/trunk/iphone/Classes/NSString%2BHTML.m
это далеко не полный, но вы можете добавить некоторые недостающие объекты отсюда: 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];
MREntitiesConverter выше - это HTML-стриппер, а не кодер.
Если вам нужен кодировщик, перейдите сюда:кодировать NSString для XML / HTML
MREntitiesConverter не работает для экранирования искаженного xml. Он не будет работать на простой URL:
http://www.google.com/search?client=safari&rls=en&q=fail&ie=UTF-8&oe=UTF-8
Если вам нужно создать литерал, вы можете использовать такой инструмент:
http://www.freeformatter.com/java-dotnet-escape.html#ad-output
для выполнения работы за вас.
см. также ответ.
Это простое решение-создать Категорию, как показано ниже:
вот файл заголовка категории:
#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);кредиты для этого ответа идет на сайт ниже: -
http://madebymany.com/blog/url-encoding-an-nsstring-on-ios
почему бы просто не использовать ?
NSData *data = [s dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; NSString *result = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; return result;нубский вопрос, но в моем случае это работает...
Это старый ответ, который я написал несколько лет назад. Мое намерение было не для того, чтобы обеспечить "хорошее" и "респектабельное" решение, а "хаки" это может быть полезно при некоторых обстоятельствах. Пожалуйста, не используйте это решение, если ничто другое не работает.
на самом деле, он отлично работает во многих ситуациях, которые другими ответы не делают, потому что UIWebView делает всю работу. И вы можете даже введите некоторый javascript (который может быть опасным и/или полезным). Спектакль должен быть ужасным, но на самом деле не так уж и плохо.
есть еще одно решение, которое нужно упомянуть. Просто создайте
UIWebViewзагрузите закодированную строку и получите текст обратно. Он экранирует теги"", а также декодирует все HTML-объекты (например,">"), и он может работать там, где другие этого не делают (например, используя кириллицу). Я не думаю, что это лучшее решение, но оно может быть полезно, если вышеуказанные решения не работают.вот небольшой пример использования Дуга:
@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
Comments