【发布时间】:2011-10-21 05:44:11
【问题描述】:
我正在开发Fahrii,它本质上是一个支持用户脚本的移动浏览器。目前,我无法在加载到 UIWebView 的网页上调用脚本。如果可能的话,我想保留这个公共 API。如果没有,至少概念证明会很好,所以我可以更好地理解它是如何工作的。我正在尝试在webViewDidFinishLoad: 方法中做到这一点。
我尝试通过读取 webView 的内容(使用 JavaScript)进行注入,然后使用 loadHTML:baseURL: 将其加载回来,但这会导致无限递归。 (完成的加载会导致脚本被注入,这反过来又会导致完成的“加载”。)
接下来,我尝试了这样的事情:
[self.browser stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"document.body.innerHTML = %@", originalHTMLWithScriptsInjected]];
脚本似乎被注入,但没有运行。
我让它工作的唯一方法是使用 ASIHTTPRequest 库来发出实际的请求,但后来我在登录表单上遇到了麻烦,除此之外,在这种情况下我必须发出两次请求。
我可能正在做一些不可能的事情,或者我只是做错了。 那么,如何在现有的 UIWebView 上调用用户脚本并使用从 Web 加载的内容?
编辑:
这里还有一些代码,包括@rich 提出的更改:
//
// Run the remaining scripts
//
NSMutableString *scriptTextToInject = [[NSMutableString alloc]init];
//
// Add each script into the page
//
for (Userscript *script in scriptsToExecute) {
//
// Read the userscript
//
NSString *scriptToLoad = [NSString stringWithContentsOfURL:[NSURL URLWithString:script.pathToScript] encoding:NSUTF8StringEncoding error:&error];
NSLog(@"Script to load: %@", scriptToLoad);
[scriptTextToInject appendFormat:@"%@\n\n",scriptToLoad];
}
NSString *documentHeadBefore = [self.browser stringByEvaluatingJavaScriptFromString:@"document.getElementsByTagName('head')[0].innerHTML"];
//
// Inject the scripts
//
NSString *scriptWrappedInATag = [NSString stringWithFormat:@"window.onload() = function(){var script = document.createElement('script');\n"
"script.charset = 'UTF-8'"
"script.setAttribute(\"type\",\"text/javascript\");\n"
"text = \"function u(){\n"
"%@"
"}\";\n"
"document.getElementsByTagName('head')[0].appendChild(script);}", scriptTextToInject];
NSLog(@"Scripts wrapped in a tag: %@", scriptWrappedInATag);
NSString *runResults = [self.browser stringByEvaluatingJavaScriptFromString:@"u();"];
NSString *documentHeadAfter = [self.browser stringByEvaluatingJavaScriptFromString:@"document.getElementsByTagName('head')[0].innerHTML"];
NSLog(@"Before: %@ \n\n\n\n After: %@", documentHeadBefore, documentHeadAfter);
【问题讨论】:
-
-stringByEvaluatingJavaScriptFromString: 是在 webview 上调用 javascript 的正确方法,但看起来你不能这样设置 document.body.innerHTML。我猜苹果希望你用 -loadHTMLString:baseURL: 方法来做到这一点。但是请描述您想要做什么,或者向我们展示您想要运行的 javascript 代码。
-
这个想法是将用户脚本注入页面。我成功的唯一方法是使用单独的请求并将响应手动加载到 WebView 中。
-
当心不要将该编辑视为“更多代码”以外的任何内容(即“包括@rich 提出的更改”可能会产生误导) 1) 为什么将它包含在
window.onload中?我认为这暗示了一个时间问题(没有一个)2)无论如何,这不是你将某些东西分配给window.onload的方式(额外的括号)3)放置在scriptWrappedInATag中的代码永远不会被调用/传递给@987654329 @.*直接跳到下面富人的回答*
标签: objective-c ios browser uiwebview userscripts