【发布时间】:2012-03-06 00:04:05
【问题描述】:
我正在尝试编写一个在 UIWebView 中使用大量 java 脚本的应用程序。并且在需要时会动态加载其中的一些 java 脚本(使用 jquery)。
index.html 和 jquery 文件按预期加载,但 code.js 文件没有加载。 code.js 文件是这样的请求(从 index.html 中截取 java 脚本代码):
function require(moduleName,filePath) {
var uri = filePath;
jQuery.ajax({
type: "GET",
url: uri,
async: false,
dataType: "script",
success: function(content) {
console.log("Receive content of "+moduleName);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
console.log("Error content of "+moduleName);
console.log("Status: " + textStatus);
console.log("Thrown error: " + errorThrown);
console.log("h" + XMLHttpRequest.getAllResponseHeaders());
console.log(XMLHttpRequest.responseText);
}
});
}
function start() {
require("test", "code.js");
}
在 index.html 的 body 标签的 onload 事件中调用 start() 函数。 code.js 文件只包含以下三行代码:
alert("Loaded file syncronosly");
// HEllo
alert("second");
我从这段代码得到的输出看起来像这样(我有一些额外的 js 代码将 console.log 调用转发到我省略的 Xcode 控制台):
UIWebView console: Error content of test
UIWebView console: Status: error
UIWebView console: Thrown error:
UIWebView console: h
UIWebView console: HTTP Error (0 error).
UIWebView console: alert("Loaded file syncronosly");
// HEllo
alert("second");
一旦我尝试在被覆盖的 NSURLCache 类中返回 code.js 的内容,我就会得到这种行为。最终的想法是拥有一个应用程序,其中一部分在 UIWebView 中运行,而无需从外部 Web 服务器加载内容。
这是缓存类(LocalSubstitutionCache)的缩写代码:
NSString *pathString = [[request URL] absoluteString];
NSLog(@"request => %@", pathString);
NSString* fileToLoad = nil;
if ([pathString isEqualToString:@"http://example.com/index.html"]) {
fileToLoad = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
}
else if ([pathString hasPrefix:@"http://example.com/code.js"]) {
fileToLoad = [[NSBundle mainBundle] pathForResource:@"code" ofType:@"js"];
}
else if ([pathString isEqualToString:@"http://example.com/jquery-1.6.2.min.js"]) {
fileToLoad = [[NSBundle mainBundle] pathForResource:@"jquery-1.6.2.min" ofType:@"js"];
}
if (!fileToLoad) {
// No local data needed for this request let super handle it:
return [super cachedResponseForRequest:request];
}
NSData *data = [NSData dataWithContentsOfFile:fileToLoad];
NSURLResponse *response =
[[NSURLResponse alloc]
initWithURL:[request URL]
MIMEType:[self mimeTypeForPath:pathString]
expectedContentLength:[data length]
textEncodingName:nil];
cachedResponse =
[[NSCachedURLResponse alloc] initWithResponse:response data:data];
(缓存代码来自这里:http://cocoawithlove.com/2010/09/substituting-local-data-for-remote.html)
现在在我的视图控制器(其中包含一个 Web 视图)中,我执行以下操作:
- (void)viewDidLoad {
[super viewDidLoad];
// This line loads the content with the cache enabled (and does not work):
[_webview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com/index.html"]]];
}
现在有趣的是,当我将 viewDidLoad 方法中的代码替换为以下代码时:
- (void) viewDidLoad {
[super viewDidLoad];
// This two line load the content without the cache:
NSString* fileToLoad = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
[_webview loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:fileToLoad]]];
}
现在一切正常,并显示了我的两个警报。所以我怀疑我在缓存中返回的内容与原始请求被缓存捕获时返回的内容不同。
这是我已经检查过的内容:
- 不使用工作案例的文件 URL。我的原始代码从 Web 服务器获取未缓存的代码。但是对于示例项目,我使用的是文件 url,因为这使项目更简单。
- 返回的内容类型。在这两种情况下都是 text/javascript
- 特殊标题集。我已经使用 http 代理检查了未缓存的请求上设置了哪些标头。没有设置特殊的标头。
我最大的问题是 jquery 错误回调没有返回任何有用的错误信息。我只是得到 textStatus 参数的错误输出。
您可以从这里下载示例项目:http://dl.dropbox.com/u/5426092/LocalCacheJsInjectTest.zip
希望有人可以帮助我
【问题讨论】:
标签: javascript ios uiwebview