-
2021-08-07 06:22:10
iOS 拦截 WebView Request 请求
相信大家都不陌生,这个在 WebView delegate 里有实现
贴一段代码1
2
3
4
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
request = [IBWebMethod formAuthorizationRequest:request];
return [IBWebMethod interceptRequest:request BaseViewController:self];
}
ture or false 来决定 WebView 是否加载请求。
可以通过 new NSURLRequest 赋给原 request 来向 request 里添加自定义的信息(头或参数)
但是由于 Ajax 请求不是刷新整个 WebView,上面的方法中无法捕获。
于是就想到了想到了通过注入 js 来 pop 出 Ajax 事件来捕获。
StackOverFlow 链接1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
var s_ajaxListener = new Object();
s_ajaxListener.tempOpen = XMLHttpRequest.prototype.open;
s_ajaxListener.tempSend = XMLHttpRequest.prototype.send;
s_ajaxListener.callback = function (){
console.log('mpAjaxHandler://' + this.url);
window.location='mpAjaxHandler://' + this.url;
};
s_ajaxListener.callbackDone = function (state,status){
console.log('mpAjaxHandlerDone://' + state + ':' + status + '/' + this.url);
window.location='mpAjaxHandlerDone://' + state + ':' + status + '/' + this.url;
};
// fake page loads.
function (){
s_ajaxListener.callbackDone(this.readyState);
this.original_onreadystatechange();
}
XMLHttpRequest.prototype.open = function(a,b){
if (!a) var a='';
if (!b) var b='';
s_ajaxListener.tempOpen.apply(this, arguments);
s_ajaxListener.method = a;
s_ajaxListener.url = b;
if (a.toLowerCase() == 'get') {
s_ajaxListener.data = b.split('?');
s_ajaxListener.data = s_ajaxListener.data[1];
}
}
XMLHttpRequest.prototype.send = function(a,b){
if (!a) var a='';
if (!b) var b='';
this.setCoustomHeader();
s_ajaxListener.tempSend.apply(this, arguments);
if(s_ajaxListener.method.toLowerCase() == 'post')s_ajaxListener.data = a;
s_ajaxListener.callback();
// Added this to intercept Ajax responses for a given send().
this.original_onreadystatechange = this.onreadystatechange;
this.onreadystatechange = override_onreadystatechange;
}
可以看到重写了 XMLHttpRequest(Ajax)的 open 与 send 方法来 pop 出事件
在捕获的事件中重新指定了 window.location 来响应 WebView 的 delegate
但是这样还不能满足我的需求,因为 Ajax 请求已经发出去了,我们需要在 Ajax 请求中加入头
上代码1
2
3
+ (NSString *)jsString:(NSString *)baseString{
return [NSString stringWithFormat:@"%@n XMLHttpRequest.prototype.setCoustomHeader = function(){ this.setRequestHeader("Authorization","%@");}", baseString, [IBDataManager sharedManager].baseAuth];
}
同样利用 js 注入把我们的头加入的 Ajax 请求中
达到了 Ajax 自定义 header 与捕获的需求
iOS UIWebView 有很大的性能和内存泄漏的问题
可以考虑将 UIWebView 与 WKWebView 封装成一套 API 来调用
最近在开发新的需求和重构代码,这段重构把 WebView 单独拿出来做成了一个 BaseWebViewController,为下一步将 UIWebView 与 WKWebView 统一做准备。
努力,认真,加油!
更多相关内容 -
iOS Webview自适应实际内容高度的4种方法详解
2021-01-04 18:40:28- (void)webViewDidFinishLoad:(UIWebView *)webView { CGFloat webViewHeight=[webView.scrollView contentSize].height; CGRect newFrame = webView.frame; newFrame.size.height = webViewHeight; webView.frame ... -
iOS WebView中使用webp格式图片的方法
2020-08-27 12:53:53由于最近项目需求,需要将项目中图片的加载做到同时兼容WebP格式,所以下面这篇文章主要给大家介绍了关于在iOS WebView中使用webp格式图片的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下 -
清除从iOSwebview点击的300ms延迟
2019-08-10 06:21:36清除从iOS webview点击的300ms延迟 -
IOS WebView 的返回缓存问题分析
2022-06-07 14:22:41IOS 的 WebView,从一个 Vue 项目跳转到另一个项目后再返回,页面数据被缓存相关工具
- IOS 模拟器
- Safari 调试器
问题描述
在一个结算列表页,发起审批流程,发起成功后再返回到该列表页,发现列表页的流程状态还是【未开始】, 这个涉及到了多项目间的跳转(甲方业务比较多,分项目开发会是一个趋势);另外,安卓没有这个问题
排查思路
按问题描述,操作一次,发现数据库状态已经改变, 但前端页面状态确实没变,刚开始以为是简单的 onLoad 和 onShow 问题。
实际上结算页和流程页实际是两个项目, 从流程项目返回结算项目后,不管页面请求写在 onLoad 还是 onShow 里,都应该会被重新执行才对; 可以从 Safari 中打开调试 WebView 的 inspector,来检查下前后端交互的过程
使用location.reload()
重新加载页面, 可以看到应用和页面各自的日志(其中 page hide 是由 Vue 路由导航触发的), 操作发起审批,进入到流程项目
最后的
App Launch
和App Show
便是流程项目的日志,再使用history.go(-2)
返回结算列表页
可以看到,虽然页面返回了结算列表页,但是并没有打印预期的 load 和 show 日志, 这些方法走不进去,写在 onShow 里请求接口再刷新状态的逻辑也就不会执行; 接下来想办法解决问题,如果能从 Web 解决的话最好,可以避免 App 更新版本打断点调试,能看到 uni-app 是通过监听
visibilitychange
事件,来触发的 onShow 和 onHide (其实 onShow 的调用方不只一个,比如首次加载时、页面回退时,都有相对应的逻辑,但跟此处关系不大)。查找这个事件的相关资料时,看到也有尝试用
pageshow
1来解决其它类型的缓存问题,先用这个事件调试一下
测试以后,结果也不理想
从这个日志也能看出来,用history.go(-2)
返回后,onLoad 方法确实没有触发, 但是 loaded 竟然又变成了 true (正常页面加载完以后,就把它变成了 false), 据此猜测,在离开一个系统时,IOS 把页面数据做了缓存,再返回这个页面时,又读取这些缓存做了渲染, 而且这种渲染不会触发上面的visibilitychange
事件(dom api)事件,pageshow
(window api) 虽然可以触发, 但是考虑到需要发起审批流程的页面会越来越多,这种写法比较复杂, 如果其他开发人员也要修改这个页面的其它逻辑,很可能带来困扰, 就放弃了这个思路(另外开发时热加载的刷新逻辑和正常逻辑也不太一样,所以还需要再兼容考虑这种情况)还是得回到从 IOS 层面解决缓存的思路上
查找了一些资料后,判断这种情况可能是属于 WKWebsiteDataTypeMemoryCache(内存缓存), 刚好之前有调整过 WebView 的标题变化,凡是页面标题变化时,都会进入此方法, 便先把逻辑放在这里,经过验证,可以解决问题
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:( NSDictionary<NSString *, id> *)change context:(void *)context { if ([keyPath isEqualToString:@"title"]) { if (object == self.webView) { self.title = self.webView.title; // clear memory cache NSSet *websiteDataTypes = [NSSet setWithArray:@[ WKWebsiteDataTypeMemoryCache, ]]; NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:0]; [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes modifiedSince:dateFrom completionHandler:^{ // done NSLog(@"------------clear---------"); }]; } else { [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } } }
微调
考虑到其实只有跨系统的时候才需要清除缓存,而大多数情况可能只是在本系统内跳转, 所以上面这个清除时机也不合适,最后突然想到了
decidePolicyForNavigationAction
这个方法经过简单验证,这个方法大致可以满足需求:单项目内的跳转不会触发这个方法, 而跳转到其它项目时会正常触发(也算 Vue 这类单页应用的前端路由特性), 所以便先把清除逻辑放在了这里面来解决问题
https://developer.mozilla.org/zh-CN/docs/Web/API/Window/pageshow_event ↩︎
-
iOS webview控件使用简介(一)
2021-06-13 12:27:45一、webview简介在IOS中,webView控件是由UIKit框架提供的一个webView类,webView控件主要为用户提供一个显示多行文本的视图功能,webview控件可以用来显示html css javascript等操作。webView控件可以用来加载本地...一、webview简介
在IOS中,webView控件是由UIKit框架提供的一个webView类,webView控件主要为用户提供一个显示多行文本的视图功能,webview控件可以用来显示html css javascript等操作。
webView控件可以用来加载本地html和网络资源。
1.1本地资源的加载采用同步方式。数据可以来源本地文件或者编码生成的html字符串。
loadHTMLString:baseURL baseURL文件路径
loadData:MIMEType:textEncodingName:baseURL MIMEType:代表MIME类型 编码集
1.2 加载网络资源,我们通常采用的异步加载的方式,常用方法有 loadRequest(该方法主要通过NSURLRequest对象)
例:IOS webView加载网络资源
1.2.1 新建一个single view application 在故事板上添加一个按钮 放入一下代码
// ViewController.h
#import < UIKit / UIKit.h>
@interface ViewController : UIViewController< UIWebViewDelegate >
- (IBAction)loadHTML:(id)sender;
@end
// ViewController.m
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
//webView开始加载新的界面时,调用
-(void)webViewDidStartLoad:(UIWebView *)webView{
NSLog(@"开始加载http://www.maomao365.com!");
}
//webView加载发生错误时调用
-(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{
NSLog(@"加载http://www.maomao365.com失败!");
}
//webView一次请求加载完毕时调用
-(void)webViewDidFinishLoad:(UIWebView *)webView{
NSLog(@"加载http://www.maomao365.com加载完毕!");
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//按钮事件
- (IBAction)loadHTML:(id)sender {
//生成一个webView
UIWebView *webViewTest = [[UIWebView alloc] initWithFrame:CGRectMake(0, 50, self.view.frame.size.width, self.view.frame.size.height-50)];
webViewTest.delegate = self;
NSURLRequest *requestTest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.maomao365.com"]];
[webViewTest loadRequest:requestTest];
[self.view addSubview:webViewTest];
NSLog(@"webView控件生成完毕!");
}
@end
运行效果:
-
iOS WebView
2017-10-24 13:31:49WebView 集成JS接口 作为基础的模块 可独立扩展JS方法 -
iOS WebView 加载 HTTP 变成 HTTPS
2022-01-14 18:36:20WebView 加载 HTTP 后变成 HTTPS问题
在使用
WKWebView
加载url
时
原来的url
是:http:
//www.xxxx.xxx
加载完成后,在代理方法里面打印原来的url
结果变成了:https:
//www.xxxx.xxx
什么👻?
原因
你的网站第一次通过
HTTPS
请求, 服务器响应Strict-Transport-Security
头,浏览器记录下这些信息,然后后面尝试访问这个网站的请求都会自动把HTTP
替换为HTTPS
方案
在请求头内添加相关参数即可
设置Strict-Transport-Security
为max-age=0
搞定!NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:<yourURL>]]; [request setValue:@"max-age=0" forHTTPHeaderField:@"Strict-Transport-Security"];
公众号
-
IOS webview调用HTML内部的方法
2021-06-29 07:30:22self.webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, ScreenWidth, ScreenHeight)];self.webView.delegate=self;[self.view addSubview:self.webView];NSURL *url = [NSURL URLWithString:@... -
ios webView与js的交互
2016-06-23 10:54:47http://blog.csdn.net/robinson_911/article/details/51741559 -
详解iOS webview加载时序和缓存问题总结
2021-01-20 10:07:21iOS webView的加载时序 UIWebView加载顺序: - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { NSLog(@开始... -
iOS开发中WebView的基本使用方法简介
2021-01-04 21:59:58在ViewController.h添加WebView成员变量和在ViewController.m添加实现 代码如下: #import @interface ViewController : UIViewController { UIWebView *webView; } @end ViewController.m – (void)viewDidLoad ... -
IOSwebview缓存
2014-11-25 15:04:10借助第三方框架 webview浏览的,缓存到本地。只需一段代码 shareSDK 分享登录 引导页 -
iosWebview的爱恨情仇—ios WebView 的input框可以不能输入
2019-09-24 10:43:49需要写一个搜索的功能,之前还是正常的,ios工程师觉得一进搜索页获取焦点会把页面顶没,所以去了获取焦点,做完这个修改后input框在ios端就不能输入了,所以问了另一个前端找了一个答案解决了,记录一下: ... -
iOS webView与JS交互、相互传值(干货)
2021-06-26 11:56:10一、webView调用js代码并向JS内传值方法一 webView 执行js 函数- (void)webViewDidFinishLoad:(UIWebView *)webView{[webView stringByEvaluatingJavaScriptFromString:@"ocCallJSFunction({'name':'vix'})"];... -
ios webView h5页面 覆盖底部安全区域小黑条
2021-12-14 17:13:04vue h5页面适配 ios底部安全区域小黑条问题 -
iOS webView以及WKWebView计算高度慢,加快加载速度等问题
2020-12-23 01:25:09我们开发详情页面,有的时候需要计算webView或者WKWebView的高度,然后再计算scrollView的高度,把webView放到scrollView上面。但是计算webView高度这个过程很耗费时间,原因是以下代理,网页彻底加载完才会计算出来... -
iOSwebview加载网页http链接被转到https的问题
2022-04-21 17:37:11iOSwebview加载网页http链接被转到https -
iOS WebView与ScrollView滑动交互
2019-06-28 16:18:32iOS WebView与ScrollView滑动交互 由于项目当中涉及webView与scrollView的滑动交互,一开始是通过计算webView的高度并且禁用webView的滑动,然后改变scrollView的contentSize去实现滑动操作,但这种做法当webView... -
iOS webview与js交互
2019-05-08 11:27:57WebView是显示网页的主要控件,在实际工作共经常会用到,尤其是当需要与用户有交互的时候,就会用到js,对于不太熟悉js的同事来说可能有点蒙,我们今天就来总结一下webview与js交互功能。 iOS12以后的版本不在支持... -
vue-bridge-webview:javascript bridge androidios webview
2021-02-06 02:38:38javascript bridge android / ios webview 安装 浏览器 [removed][removed] [removed][removed] 包装经理 npm install vue-bridge-webview --save import Vue from ' vue ' import VueBridgeWebview f -
IOS WebView与JavaScript交互实现Web App
2015-08-13 14:57:08IOS加载bundle里的html并实现WebView与JavaScript的交互 -
ios WebView 页面缓存
2019-08-06 01:34:32NULL 博文链接:https://zhangmingwei.iteye.com/blog/2092097 -
ios webview加载本地网页并解决乱码问题
2021-06-25 05:44:13例如 NSString *htmlpath = [[[NSBundle mainBundle]resourcePath]stringByAppendingPathComponent@"xx.html"];NSString *htmlstring = [NSString stringWithContentsOfFile:...[webview loadHTMLString:htmlst... -
iOS webView 禁止缩小放大 捏合
2018-06-23 15:56:20首先想到的方法是我们会设置下面这个属性:_webView.scalesPageToFit = NO;但是通常情况下为了web可以自适应设备尺寸还是将 _webView.scalesPageToFit = YES;这样做的同时,在webView上进行双击或捏合、放大等操作... -
iOS webview中调用相机相册崩溃问题
2019-12-24 17:09:12在webview中原生与H5交互时使用到原生调用相机或者相册时 [self presentViewController:picker animated:YES completion:nil]; 出现: accessing _cachedSystemAnimationFence requires the main thread 异常崩溃... -
iOS webview加载中文链接
2019-10-08 13:37:00项目中一个老的问题,在webview中有一个链接里边包含中文链接是 https://baike.baidu.com/item/笕桥中央航校#hotspotmining 原来的处理是对urlString进行转码 NSURL * url = [NSURL URLWithString:[urlString ... -
iOS WebView 加载本地资源(图片,文件等)
2019-03-20 16:02:00iOS WebView 加载本地资源(图片,文件等) NSString *path = [[NSBundle mainBundle] pathForResource:@"关于.docx" ofType:nil]; NSURL *url = [NSURL fileURLWith... -
iOS WebView 忽略不受信任的https证书(SSL)
2020-03-21 15:06:50大家在开发过程中经常会使用到WebView,但是在使用WebView经常回家再Https,可是有一些Https是不受信任的,这个时候我们就要跳过这个Https信任这个过程,那我们如何跳过这个过程呢? 为了方便使用,我们创建一个...