WKWebview 注入header

WKWebview 注入header,第1张

header请求头这种最好是不通过服务器,比如如果通过服务器NGINX配置,会出现很多问题,包括请求头丢失,请求头拦截,最好的方式通过直接跟web直接交互,比如WebViewJavascriptBridge或者原生自带的方式做交互,更方便,如果有更好的方案留言给我,阿里嘎多

在WKwebview因为加载请求是个异步 *** 作,所以在初次webview loadrequest时候不需要加入header ,而是拦截webview的请求 ,在请求头中加入header,并且重复请求,但是还有一定问题 ,有时会有header丢失问题,所以我觉得最优解决方案是通过交互传参数可以解决这个问题,如果有更好方案请告诉我。

遇到一个需求:在网页抛出一切请求时,不管是资源请求还是重定向等,需要拦截掉并在header添加信息,ng拿到去做处理,访问不同资源服务器。

一开始想到的方式是:通过WKNavigationDelegate的代理方法- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler

来在请求之前获得请求信息,并把请求头信息添加进去,如下:

-(void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{

    NSLog(@"灰度测试h5Url: %@",navigationAction.request.URL.absoluteString)

    if ([navigationAction.request.URL.absoluteString containsString:OUR_URL_ID]) {

        // 拦截所有网络请求头,重新添加参数请求头信息

        NSMutableURLRequest *mutableRequest = [navigationAction.request mutableCopy]

        NSDictionary *requestHeaders = navigationAction.request.allHTTPHeaderFields

        if ([requestHeaders isKindOfClass:[NSDictionary class]]) {

            //简单通过Version_Key判断下是否已经加入了请求信息

            if ([AFNetWorkManager KeyUrlrequestOneNull:requestHeaders]) {

                [AFNetWorkManager addWebDefaultKeyUrlrequest:mutableRequest]

                [webView loadRequest:mutableRequest]

                NSLog(@"灰度测试h5Url: %@ \n请求头:%@",navigationAction.request.URL.absoluteString,mutableRequest.allHTTPHeaderFields)

                decisionHandler(WKNavigationActionPolicyCancel)

                return

            }else{

                //参数正常,放开请求

                NSLog(@"灰度测试h5Url: %@ \n请求头:%@",navigationAction.request.URL.absoluteString,requestHeaders)

                decisionHandler(WKNavigationActionPolicyAllow)

            }

        }else{

            //没有请求头,加上新的请求头,并赋予参数

            mutableRequest.allHTTPHeaderFields = [NSMutableDictionary new]

            [AFNetWorkManager addWebDefaultKeyUrlrequest:mutableRequest]

            [webView loadRequest:mutableRequest]

            NSLog(@"灰度测试h5Url: %@ \n请求头:%@",navigationAction.request.URL.absoluteString,mutableRequest.allHTTPHeaderFields)

            decisionHandler(WKNavigationActionPolicyCancel)

        }

    }else{

        //本地请求资源,pdf等

        decisionHandler(WKNavigationActionPolicyAllow)

    }

}

但是经过打印发现,只拦截了一些html请求,向png、css、js资源请求,并没有拦截到,甚至没有走这个方法。

无奈,只能网上搜索,结果发现了:https://github.com/fenglee594/WKWebViewRequestHook

这个demo,稍加改动,亲测有效。

用户在登录后获取了token值并保存在本地,应用内WebView加载网页时,前端处理token先读取header的该字段,再存到LocalStrorage里,也就是要求客户端在loadUrl的时候,要把token先放到header里,传递给web做登录校验。

通过查看API可用loadUrl(String url, Map<String, String>additionalHttpHeaders)

实际测试时,该方案并不生效,无论authorization大小写均不生效。

和前端联调的结果显示我们没有传这个值,甚至自定义的值都没有写进去。

最终反应出来的效果是没有认证,也就无法进行数据渲染。

但使用Charles抓包显示,在load网页的时候确实在header里有token字段,包括diy字段。

最初的以为是没有LocalStroage的读写权限,随即打开webview的存储开关:

https://yq.aliyun.com/ziliao/150552

测试结果,仍然不行。

查看stackoverflow碰到了差不多的情况

https://stackoverflow.com/questions/7610790/add-custom-headers-to-webview-resource-requests-android

其中有给到解决方案,就是在WebViewClient()的回调方法shouldInterceptRequest里自行处理所有的web渲染

测试结果,该方案能正常渲染,但是问题又来了,在里面点击跳转(非跨域访问),无法正常渲染下一界面。

按照前端同事的说法,他们也是读取header里的值,把token取出来放到LocalStorage里,之后就去拿LocalStorage的值,直接setHeader的方案不行,那么我们就直接帮他们放到存储里。

这里采用java调用js方案

https://www.v2ex.com/t/377333

js注入的时机有很多,比如以下

最终是选择在onReceivedTitle 的回调里注入js

测试通过,跳转也正常。

目前怀疑是authorization不让被复写,具体原因未来得及验证。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/bake/11374925.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-15
下一篇2023-05-15

发表评论

登录后才能评论

评论列表(0条)

    保存