Tôi đang cố gắng viết một ứng dụng sử dụng rất nhiều tập lệnh java bên trong một UIWebView. Và một số kịch bản java này được nạp động (với jquery) khi nó là cần thiết.Tự động tải các tệp javascript trong UIWebView với bộ đệm cục bộ không hoạt động
Tệp index.html và tệp jquery được tải như mong đợi nhưng không tải tệp code.js. Các tập tin code.js là yêu cầu như thế này (snipped của mã java script từ index.html):
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");
}
Các hàm start() được gọi trong sự kiện onload của thẻ cơ thể của index.html. Các code.js nộp chỉ chứa ba dòng mã sau đây:
alert("Loaded file syncronosly");
// HEllo
alert("second");
Kết quả tôi nhận được từ mã này trông như thế này (tôi có mã số bổ sung js đó chuyển tiếp cuộc gọi đến console.log Xcode console mà Tôi bỏ qua):
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");
Tôi nhận được hành vi này ngay khi tôi cố trả lại nội dung của code.js trong lớp NSURLCache đã ghi đè. Ý tưởng cuối cùng là có một ứng dụng mà một phần chạy trong một UIWebView mà không cần tải nội dung từ một máy chủ web bên ngoài.
này được mã rút gọn của lớp bộ nhớ cache (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];
(Mã bộ nhớ cache là từ đây: http://cocoawithlove.com/2010/09/substituting-local-data-for-remote.html)
Bây giờ trong điều khiển điểm của tôi (trong đó có một cái nhìn web) Tôi làm như sau:
- (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"]]];
}
Điều thú vị là khi tôi thay thế mã trong phương thức viewDidLoad bằng mã sau:
- (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]]];
}
Bây giờ tất cả đều hoạt động tốt và tôi nhận được hai cảnh báo của mình được hiển thị. Vì vậy, tôi nghi ngờ rằng những gì tôi đang trở lại trong bộ nhớ cache không giống như những gì yêu cầu ban đầu là trở lại khi nó được bắt bởi bộ nhớ cache.
Dưới đây là những gì tôi đã kiểm tra cho:
- Không sử dụng url tập tin đối với trường hợp làm việc. Mã ban đầu của tôi lấy mã không được lưu trong bộ nhớ cache từ máy chủ web. Nhưng đối với dự án ví dụ tôi đang sử dụng các url của tệp vì điều này làm cho dự án đơn giản hơn.
- Loại nội dung được trả lại. Có trên cả hai trường hợp văn bản/javascript
- Các tiêu đề đặc biệt được đặt. Tôi đã kiểm tra với một proxy http những gì tiêu đề được thiết lập trên yêu cầu mà không được lưu trữ. Không có tiêu đề đặc biệt nào được đặt.
Vấn đề lớn nhất của tôi là cuộc gọi lại lỗi jquery không trả về bất kỳ thông tin lỗi hữu ích nào. Tôi chỉ nhận được một đầu ra lỗi cho đối số textStatus.
Bạn có thể tải dự án ví dụ từ đây: http://dl.dropbox.com/u/5426092/LocalCacheJsInjectTest.zip
Hope ai đó có thể giúp tôi đây
Các NSHTTPURLResponse initWithURL: statusCode: Phương pháp có sẵn từ 5.0 mặc dù nó không xuất hiện trong tài liệu. Điều này thật kỳ lạ, chúng ta có thể sử dụng nó không? – groumpf
Tôi giả định rằng chúng ta có thể sử dụng phương thức này khi nó được thêm vào và nằm trong tệp tiêu đề có thể nhìn thấy thông thường cho lớp này. Nhưng cho đến nay tôi không có ứng dụng nào có mã này trong cửa hàng ứng dụng để nó có thể khác nhau. – Chris
Tôi hiện đã gửi thành công ứng dụng của mình bằng phương pháp đã đề cập. Không có vấn đề với nó. – Chris