我有一串ASCII字符(由[NSString stringWithFormat:@“%c”,someNumber]随机创建),我想使用该字符串作为javascript方法的输入。类似的东西:
[webView_ stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"my_javascript_method(\"%@\")", myASCIIString]];
如何逃避NSString?我试着查看encodeURI和decodeURI,但还没有找到任何解决方案。
答案 0 :(得分:13)
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];
答案 1 :(得分:9)
经过无数个小时研究解决方案后,我想出了什么。结果我遇到了一个问题,我没有逃过回车\ r \ n这个功能解决了我的问题。
-(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
答案 2 :(得分:5)
通过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];
答案 3 :(得分:1)
Here's the relevant part of the ES5 specification:
除了结束引号字符,反斜杠,回车符,行分隔符,段落分隔符和换行符之外,所有字符都可以按字面意思显示在字符串文字中。任何字符都可能以转义序列的形式出现。
某些字符存在反斜杠转义(您可以找到几页),任何字符都可以用十六进制表示为\uXXXX
。它们(在示例中)在规范中向下解释了几页。
答案 4 :(得分:1)
如果您需要一个可以使用扩展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;
}
我不知道这对于unichar可表示的代码点的行为如何。似乎这些字符也无法用javascript表示。
答案 5 :(得分:0)
你有没有尝试过类似的东西:
[webView_ stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"my_javascript_method(escape(\"%@\"))", myASCIIString]];
将转义函数放入字符串调用可能对您有用。这真的取决于你想要逃脱的原因
答案 6 :(得分:0)
以上是@ zetachang的回答。你必须在javascript函数的参数中使用双引号。如,
NSString *javascriptCall =
[NSString stringWithFormat:@"MyJavascriptFunction(\"%@\")", escapedString];
[self.webView stringByEvaluatingJavaScriptFromString:javascriptCall];
答案 7 :(得分:0)
我使用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