在 UIWebView 中加载包含 SVG 的 HTML5,同时保持 localStorage 可用

发布于 2024-10-17 20:15:25 字数 1298 浏览 6 评论 0原文

我正在开发一个 iPhone 应用程序,它利用 UIWebView 来显示基于 HTML5 的页面。要求包括:

1:页面需要渲染内联SVG。
2:页面需要访问localStorage。

为了获得正确的 mime 类型以便内联 SVG 可以工作,我首先尝试使用下面的代码来填充 Web 视图:

NSString *resourcePath = [[NSBundle mainBundle] resourcePath]; 
NSURL *baseURL = [[NSURL alloc] initFileURLWithPath:resourcePath];
[self.webView loadData:htmlData 
 MIMEType:@"application/xhtml+xml"  
 textEncodingName:@"UTF-8" 
 baseURL:baseURL];

但是,在尝试此技术时,我在尝试访问本地存储时不断引发 SECURITY_ERR 异常: 有关 localStorage 和 SECURITY_ERR 的 W3C 文档

我发现有人遇到了同样的问题,并且他们认为这是由于域名起源造成的: 帖子涵盖了 UIWebView 和 localStorage 访问问题

他们通过使用 NSURLRequest 解决了问题:

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];

这确实似乎解决了我的 localStorage 问题,但这会破坏我的 SVG,因为我不知道在这种情况下如何显式设置 mime 类型。

所以,问题是,如何加载具有正确 mime 类型的内联 svg 数据,同时仍保持文档的来源符合 localStorage 要求?

感谢您的帮助:)

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 :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

§对你不离不弃 2024-10-24 20:15:25

您是否尝试过创建 NSMutableURLRequest 并将 mime 类型添加为 HTTP 标头字段?

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:baseURL];
[request addValue:@"application/xhtml+xml" forHTTPHeaderField:@"Content-Type"];

维基百科上的 标头字段列表 表示这仅用于 put 和 post 请求,但它可能值得一试。

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.

满栀 2024-10-24 20:15:25

我用它来直接加载我的 .svg 文件:

    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];

这一切都可以,但有时我用它来加载一个 .html 文件,该文件调用/加载外部 .svg 文件:

NSString* urlAddress = [[NSBundle mainBundle] pathForResource:@"fileWithAMap" ofType:@"html";

其中 fileWithAMap.html 的内容是:

<!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>

而且效果也很好

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

寄居者 2024-10-24 20:15:25

今天我感到精神焕发,很大程度上要归功于 @JimDusseau 提供了一种解决问题的新颖尝试(我必须承认我已经放弃了让它发挥作用。)不幸的是,吉姆的方法适用于该请求,但它仍然没有对响应的影响。

然后我在谷歌上搜索了两个小时,试图找到其他选项,其中之一是试图将 mime 类型与特定的文件扩展名相关联,等等。

所有这些谷歌搜索都没有结果,但它确实触发了对另一个文件扩展名的模糊记忆......

.xhtml

使用此文件扩展名是否会导致使用适当的 MIME 类型来处理请求?我的心开始狂跳,我能感觉到血液在我的血管中流淌,带着极大的期待,我进行了编辑并重建了项目,发现[鼓声]......

是的!是的!是的! iPhone 使用适当的 mime 类型来处理响应,并保持文档来源适合 localStorage。

这是工作代码:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"xhtml"];
NSURL *baseURL = [NSURL fileURLWithPath:filePath];
NSURLRequest *request = [NSURLRequest requestWithURL:baseURL];
[webView loadRequest:request];

简单,但难以捉摸(到目前为止。)

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.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文