我有一串ASCII字符(由[NSString stringWithFormat:@"%c", someNumber]随机创建),我想使用该字符串作为javascript方法的输入。比如:
[webView_ stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"my_javascript_method("%@")", myASCIIString]];
如何转义NSString?我试图查看encodeURI和decodeURI,但还没有找到任何解决方案。
NSJSONSerialization
就在角落里。将NSString转义为Javascript字符串字面值很难,而且很容易出错。(JSONKit
使用代码行来处理它https://github.com/johnezang/JSONKit/blob/82157634ca0ca5b6a4a67a194dd11f15d9b72835/JSONKit.m#L1423)
下面是一个小的类别方法来转义NSString
对象。
#import "NSString+JavascriptEscape.h"
@implementation NSString (JavascriptEscape)
- (NSString *)stringEscapedForJavasacript {
// valid JSON object need to be an array or dictionary
NSArray* arrayForEncoding = @[self];
NSString* jsonString = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:arrayForEncoding options:0 error:nil] encoding:NSUTF8StringEncoding];
NSString* escapedString = [jsonString substringWithRange:NSMakeRange(2, jsonString.length - 4)];
return escapedString;
}
@end
还有一点需要注意,你必须在javascript函数的参数中使用双引号。例如,
NSString *javascriptCall =
[NSString stringWithFormat:@"MyJavascriptFunction("%@")", escapedString];
[self.webView stringByEvaluatingJavaScriptFromString:javascriptCall];
经过无数个小时的研究,我想出了一个解决方案。原来我遇到了一个问题,我没有转义回车r,所以这个函数解决了我的问题。
-(NSString *)addBackslashes:(NSString *)string {
/*
Escape characters so we can pass a string via stringByEvaluatingJavaScriptFromString
*/
// Escape the characters
string = [string stringByReplacingOccurrencesOfString:@"\" withString:@"\\"];
string = [string stringByReplacingOccurrencesOfString:@""" withString:@"\""];
string = [string stringByReplacingOccurrencesOfString:@"'" withString:@"\'"];
string = [string stringByReplacingOccurrencesOfString:@"n" withString:@"\n"];
string = [string stringByReplacingOccurrencesOfString:@"r" withString:@"\r"];
string = [string stringByReplacingOccurrencesOfString:@"f" withString:@"\f"];
return string;
}
这是我发现的一个很好的网站,它引导我找到了这个解决方案。http://www.wilsonmar.com/1eschars.htm
通过ASCII,我假定您的意思是它是0x00到0x7F范围内的字节。在这个范围内,根据http://www.json.org,您唯一需要转义的字符是、
"
和控制字符:0x00-0x1F和0x7F。如果你在做简单的替换,控制字符会变得有点棘手,所以我会一个字符一个字符地转义字符串,可能是这样的(根本没有测试):
const char *chars = [myASCIIString UTF8String];
NSMutableString *escapedString = [NSMutableString string];
while (*chars)
{
if (*chars == '\')
[escapedString appendString:@"\\"];
else if (*chars == '"')
[escapedString appendString:@"\""];
else if (*chars < 0x1F || *chars == 0x7F)
[escapedString appendFormat:@"\u%04X", (int)*chars];
else
[escapedString appendFormat:@"%c", *chars];
++chars;
}
NSString *js = [NSString stringWithFormat:@"my_js_function("%@")", escapedString];
以下是ES5规范的相关部分:
除结束引号、反斜杠、回车、行分隔符、段落分隔符和换行符外,所有字符都可以在字符串字面上出现。任何字符都可以以转义序列的形式出现。
对于某些字符有反斜杠转义(您可以在后面几页找到),并且任何字符都可以用十六进制表示为uXXXX
。
如果你需要一个解决方案,将工作与扩展ASCII符号(如拉丁符号)和/或unicode,你可以使用这个:
- (NSString*) escapeStringForJavascript:(NSString*)input
{
NSMutableString* ret = [NSMutableString string];
int i;
for (i = 0; i < input.length; i++)
{
unichar c = [input characterAtIndex:i];
if (c == '\')
{
// escape backslash
[ret appendFormat:@"\\"];
}
else if (c == '"')
{
// escape double quotes
[ret appendFormat:@"\""];
}
else if (c >= 0x20 && c <= 0x7E)
{
// if it is a printable ASCII character (other than and "), append directly
[ret appendFormat:@"%c", c];
}
else
{
// if it is not printable standard ASCII, append as a unicode escape sequence
[ret appendFormat:@"\u%04X", c];
}
}
return ret;
}
我不知道上面的代码点是如何用单字符表示的。这些字符似乎也无法在javascript中表示。
您是否尝试过类似的操作:
[webView_ stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"my_javascript_method(escape("%@"))", myASCIIString]];
只需将转义函数放入string调用中就可以了。这取决于你为什么要转义
这是@zetachang上面的回答的后续。你必须在javascript函数的参数中使用双引号。例如,
NSString *javascriptCall =
[NSString stringWithFormat:@"MyJavascriptFunction("%@")", escapedString];
[self.webView stringByEvaluatingJavaScriptFromString:javascriptCall];
我将使用NSJSONSerialization
将字符串转换为JSON数组,然后将结果JSON字符串粘贴到JavaScript函数参数中。这样,我就不必担心JSON字符串是否包含在单引号或双引号中。
NSString* inputString = ... // your raw string to escape
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:@[inputString] options:0 error:nil];
NSString* jsString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSString* jsScript = [NSString stringWithFormat:@"yourFunction(%@[0])",jsString];
// then pass jsScript to a JavaScript interpreter