Skip to content

Instantly share code, notes, and snippets.

@uasi
Last active January 27, 2016 08:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save uasi/e30f0f9bd8e596c18174 to your computer and use it in GitHub Desktop.
Save uasi/e30f0f9bd8e596c18174 to your computer and use it in GitHub Desktop.
WebView からサンドボックス内のローカルファイルを読み込もうとするリクエストを書き換えるやつ
@interface MyWebViewController : NSObject
@property IBOutlet WebView *webView; // nib 内の WebView に接続済みということで
@end
@implementation MyWebViewController <WebResourceLoadDelegate>
- (void)awakeFromNib {
// WebView にデリゲートを接続
self.webView.resourceLoadDelegate = self;
}
// file スキームの URL か?
static BOOL hasFileURL(NSURLRequest *request) {
return [request.URL.scheme.lowercaseString isEqualToString:@"file"];
}
// file:///path/to/MyApp.app/Contents/Resources/... な URL だけ許可
static BOOL hasAllowedPath(NSURLRequest *request) {
return ...;
}
// file://... を file:///path/to/MyApp.app/Contents/Resources/... に書き換える
static NSURLRequest *rewriteRequest(NSURLRequest *baseRequest) {
if (!hasFileURL(baseRequest) || hasAllowedPath(baseRequest)) {
return baseRequest;
}
NSString *resourceURL = [[NSBundle mainBundle] resourceURL].absoluteString;
NSString *baseURL = baseRequest.URL.absoluteString;
NSString *newURL = [baseURL stringByReplacingOccurrencesOfString:@"file://" withString:resourceURL options:NSCaseInsensitiveSearch range:NSMakeRange(0, @"file://".length)];
NSMutableURLRequest *request = [baseRequest mutableCopy];
request.URL = [NSURL URLWithString:newURL];
return request;
}
// WebView からのあらゆるリクエスト(img src, AJAX など含む)を送信する前に呼ばれるデリゲートメソッド
- (NSURLRequest *)webView:(WebView *)sender
resource:(id)identifier
willSendRequest:(NSURLRequest *)request
redirectResponse:(NSURLResponse *)redirectResponse
fromDataSource:(WebDataSource *)dataSource {
return rewriteRequest(request);
}
@uasi
Copy link
Author

uasi commented Jan 27, 2016

WebView から飛ぶリクエストを送信前にフックする。リクエスト先が file スキームの URL で、かつアプリ自身のリソースフォルダを指していないなら、 URL のルートをリソースフォルダに差し替える。

以下の対策は不十分:

  • WebView に表示する HTML に <base href="file:///.../Resources"> を埋め込む
  • WebView に HTML を流し込むとき -[WebFrame loadHTMLString:baseURL:] の baseURL に file:///.../Resources" を指定する

base URL をこれらの方法で設定しても、絶対パスを指定したリクエストには影響しない。

@uasi
Copy link
Author

uasi commented Jan 27, 2016

書き換え後の URL、 file:///path/to/MyApp.app/Contents/Resources/EmptyDirectory のほうがいいかも。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment