美文网首页ios iOS Developer
本地html加载时带参数的问题

本地html加载时带参数的问题

作者: anjohnlv | 来源:发表于2017-04-14 15:08 被阅读798次

先阐述背景:

app需要集成一个本地的html文件,并且在调用时url带参数。如:
analysis.html?sId=417492&apiUrl=http://192.168.100.1:8888

1、传统方法。

首先我采取了之前的本地网页集成方法

//htmlPath即是本地html的路径,filename即是html名
NSString *filePath = [htmlPath stringByAppendingPathComponent:filename];
NSString *htmlString = [[NSString alloc]initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
[webView loadHTMLString:htmlString baseURL:[NSURL fileURLWithPath:htmlPath]];

传入文件名filename = @"analysis.html?sId=417492&apiUrl=http://192.168.100.1:8888";
发现htmlString为空,并不能通过带参数的文件地址找到对应的文件。
后来也试过NSString的initWithContentsOfURL等方法。均无法实现需求。
放弃。

2、relativeToURL

之后我找到了另一个方法

NSString *filePath = [htmlPath stringByAppendingPathComponent:filename];
NSURL *fileUrl = [NSURL URLWithString:@"?sId=417492&apiUrl=http://192.168.100.1:8888"
                    relativeToURL:[NSURL fileURLWithPath:filePath]];
NSURLRequest *request = [NSURLRequest requestWithURL: fileUrl];
[webView loadRequest:request];

经试验,该方法可以正常打开html文件,并将参数传入。
需要注意的是,有时候我们发现使用[NSURL URLWithString:filePath]也可以达到相同的效果,在UIWebView是这样的,但放到WKWebView就行不通了,所以还是建议统一使用:[NSURL fileURLWithPath:filePath]

问题解决,于是轻松加惬意得继续扩展。还有没有更简单的方法呢?

3、直接拼URL

基于方法二,既然通过url,为什么不能直接将参数拼接在url后面呢。仔细看,其实这种用法其实很像网络请求的Get方法,所以

//htmlPath即是本地html的路径,filename=@"analysis.html?sId=417492&apiUrl=http://192.168.100.1:8888"
NSString *filePath = [htmlPath stringByAppendingPathComponent:filename];

接下来将path转化为url就好了吧?

NSURL *fileUrl = [NSURL fileURLWithPath: filePath];
NSURLRequest *request = [NSURLRequest requestWithURL: fileUrl];
[webview loadRequest:request];

然而并没有。网页并没有加载显示出来,自然参数也并没有传递进去。难道我想错了?
打印一下url发现

Printing description of fileUrl:
file:///var/containers/Bundle/Application/39A2343F-37E1-42B4-8D7E-F373A153BF1D/UrlDemo.app/statis/analysis.html%3FsId=417492&apiUrl=192.168.100.1:8888

发现问题:url中的"?"被转码成"%3F",直接导致整个url的解析失败。再然后,我试过对参数编码,对path编码,最后发现,是在方法二中建议使用的fileURLWithPath:的问题,在该方法中,会自动进行编码。不推荐使用的URLWithString:方法反而不会。于是为了解决编码问题,我尝试着使用URLWithString将Path转化成URL

NSURL *fileUrl = [NSURL URLWithString:[NSString stringWithFormat:@"file://%@", filePath]];

就是手动拼接一个文件头。打印url正常,编译正常,运行正常,正确打开网页并传递了参数。

但是总觉得手动拼一个头做法不太正规,于是继续挖坑。

4、NSURLComponents

直接上代码

NSString *filePath = [htmlPath stringByAppendingPathComponent:filename];
NSURL *fileUrl = [NSURL fileURLWithPath:filePath isDirectory:NO];//此部分没有?所以没有问题,isDirectory=YES会导致多一层目录。
NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:fileUrl resolvingAgainstBaseURL:NO];
[urlComponents setQueryItems:@[[NSURLQueryItem queryItemWithName:@"sId" value:@"417492"], [NSURLQueryItem queryItemWithName:@"apiUrl" value:@"http://192.168.100.1:8888"]]];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:urlComponents.URL];

正确实现需求。

综上,解决问题的方法永远不止一个。
不求甚解是一种态度;
浅尝辄止是一种态度;
刨根问底是一种态度;
精益求精是一种态度。


浅尝辄止了~

相关文章

网友评论

  • pFruHMXB:的确,楼主说的方法智能在模拟器上使用.
  • a69d93030256:NSString *JSON = [NSString stringWithFormat:@"?fileUrl=%@",param];
    NSURL *url = [NSURL fileURLWithPath:path];
    NSURL *now = [NSURL URLWithString:JSON relativeToURL:url];
    wkWebView.navigationDelegate = self;
    [wkWebView.configuration.preferences setValue:@YES forKey:@"allowFileAccessFromFileURLs"];
    [wkWebView loadRequest:[NSURLRequest requestWithURL:now]];
    老干妈拌饭:wkwebview 用你写的这种或者楼主的都是在真机上加载不了,模拟器可以 HTML在document目录下
    anjohnlv:@a69d93030256 给你点赞
    a69d93030256:楼主可以试试 ,我这么写的可以!
  • ce2f22ad95cd:你好,为什么我用了上面的方法没有用
    anjohnlv:文中提到的方法其实是一个思索的过程。
    其中方法1是失败的方法;方法2是有局限性的方法;方法3是手动拼字符串,可以解决问题但不推荐的方法;方法4是最终我找到的相对能解释通的方法。
    你把原理看明白就知道了。

本文标题:本地html加载时带参数的问题

本文链接:https://www.haomeiwen.com/subject/ahgbattx.html