Loading HTML5 containing SVG in UIWebView whilst keeping localStorage available
I'm developing an iphone app that makes use of of a UIWebView to display an HTML5-based page. The requirements include:
1: The page needs to render inline SVG.
2: The page needs to access localStorage.To get the mime type right so the 开发者_如何学运维inline SVG would work, I first tried using the code below to populate the web view:
NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
NSURL *baseURL = [[NSURL alloc] initFileURLWithPath:resourcePath];
[self.webView loadData:htmlData
MIMEType:@"application/xhtml+xml"
textEncodingName:@"UTF-8"
baseURL:baseURL];
However, when trying this technique, I kept elliciting SECURITY_ERR exceptions when trying to access local storage: W3C documentation on localStorage and SECURITY_ERR
I found someone who had the same issue, and they believed it was due to the domain origin: Post covering issues with UIWebView and localStorage access issues
They resolved their issue by using an NSURLRequest instead:
NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:[path stringByAppendingString:@"path and file name of the file"]];
NSURLRequest *request = [NSURLRequest requestWithURL:baseURL];
[webView loadRequest:request];
This does seem to resolve my localStorage issues, however this breaks my SVG because I'm not aware of how to explicitly set the mime type in this case.
So, the question is, how do I load the data with the correct mime type for inline svg while still keeping the document's origin compliant with localStorage requirements?
Thank you for your help :)
Have you tried to create a NSMutableURLRequest and add the mime type as a HTTP header field?
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:baseURL];
[request addValue:@"application/xhtml+xml" forHTTPHeaderField:@"Content-Type"];
The list of header fields on wikipedia says this is used for put and post requests only, but it might be worth a shot.
i'm using this to load directly my .svg file:
CGRect webFrame;
webFrame = CGRectMake(0.0, 0.0, 480, 320);
UIWebView *webView;
webView = [[UIWebView alloc] initWithFrame:webFrame];
[[self view] addSubview:webView];
webView.delegate = self;
[webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitTouchCallout = 'none'"];
NSString* urlAddress = [[NSBundle mainBundle] pathForResource:@"mappaSVG" ofType:@"svg"];
NSURL* url = [NSURL fileURLWithPath: urlAddress];
NSURLRequest* requestObj = [NSURLRequest requestWithURL: url];
[[self webView] loadRequest: requestObj];
webView.scalesPageToFit = YES;
[super viewDidLoad];
and it's all ok with this, but sometimes i use this to load a .html file which call/load an external .svg file:
NSString* urlAddress = [[NSBundle mainBundle] pathForResource:@"fileWithAMap" ofType:@"html";
where the content of fileWithAMap.html is:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="yes" name="apple-mobile-web-app-capable" />
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<meta name='viewport' content='initial-scale=1.4; maximum-scale=9.0; minimum-scale=0.07; user-scalable=1;' />
<title>My Title</title>
</head>
<body leftmargin="0" topmargin="0" marginwidth="0" marginheight="0">
<div id="content">
<embed src="mappaSVG.svg" width="3840" height="3200" type="image/svg+xml" />
</div>
</body>
</html>
and it works fine too
I felt reinvigorated today, in large part thanks to @JimDusseau providing a novel attempt to solve the problem (I must confess I'd given up on getting this to work.) Unfortunately, Jim's approach works for the request, but it still had no effect on the response.
I then Googled for 2 hours trying to find other options, one of which was trying to associate a mime type with particular file extensions, etc.
All of this Googling proved fruitless, but it did trigger a vague memory of another file extension...
.xhtml
Could using this file extension cause the request to be handled with the appropriate mime type? My heart started pounding, I could feel the blood coursing through my veins, and, with great anticipation, I made the edit and rebuilt the project to find that [drumroll]...
YES! YES! YES! The iphone treats the response with the appropriate mime type AND keeps the document origin happy for localStorage.
Here's the working code:
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"xhtml"];
NSURL *baseURL = [NSURL fileURLWithPath:filePath];
NSURLRequest *request = [NSURLRequest requestWithURL:baseURL];
[webView loadRequest:request];
Simple, yet elusive (until now.)
精彩评论