美文网首页
iOS--WKWebView加载Post请求丢失body的解决方

iOS--WKWebView加载Post请求丢失body的解决方

作者: mayuee | 来源:发表于2020-01-13 16:12 被阅读0次

WKWebView通过loadrequest方法加载Post请求会丢失请求体(body)中的内容,进而导致服务器拿不到body中的内容的问题的发生。这个问题的产生主要是因为WKWebView的网络请求的进程与APP不是同一个进程,所以网络请求的过程是这样的:由APP所在的进程发起request,然后通过IPC通信(进程间通信)将请求的相关信息(请求头、请求行、请求体等)传递给webkit网络线进程接收包装,进行数据的HTTP请求,最终再进行IPC的通信回传给APP所在的进程的。这里如果发起的request请求是post请求的话,由于要进行IPC数据传递,传递的请求体body中根据系统调度,将其舍弃,最终在WKWebView网络进程接受的时候请求体body中的内容变成了空,导致此种情况下的服务器获取不到请求体,导致问题的产生。(摘自链接:关于WKWebView的post请求丢失body问题的解决方案 - 简书

上面的问题通过测试发现在iOS11之后已修复,但是App还要支持iOS11之前的系统,所以还是需要解决这个问题。

解决思路

创建一个form表单,将需要post的数据填到表单,模拟form表单提交实现数据传输。

实现基础

新建一个头文件 WKWebViewFormDefine.h,里面定义了一个宏:

#define POST_JS @"function my_post(path, params) {\

var method = \"POST\";\

var form = document.createElement(\"form\");\

form.setAttribute(\"method\", method);\

form.setAttribute(\"action\", path);\

form.setAttribute(\"accept-charset\", \"UTF-8\");\

for(var key in params){\

if (params.hasOwnProperty(key)) {\

var hiddenFild = document.createElement(\"input\");\

hiddenFild.setAttribute(\"type\", \"hidden\");\

hiddenFild.setAttribute(\"name\", key);\

hiddenFild.setAttribute(\"value\", params[key]);\

}\

form.appendChild(hiddenFild);\

}\

document.body.appendChild(form);\

form.submit();\

}"

上面定义了一个my_post方法,需要传入两个参数:path和params,path是请求的URL的字符串,path是放到body中的参数,函数实现创建form表单并填入params的参数,最后commit提交,实现post请求。这个宏网上基本都能找到,但是实际使用中,当params中的汉字会出现乱码,上面已经补充,给from设置 accept-charset 问题解决。

实际使用

1、请求的url

    urlStr = @''";

2、需要传入的参数字典

    NSDictionary *params = @{@"key":@"value"};

3、将参数字典转成Json字符串

    NSString*jsonString = [selfjsonStringFromDictionary:params];

4、包装成需要执行的 js 字符串,注意 my_post 是宏定义中的方法名,POST_JS是宏定义名称,需要一一对应!

    NSString*jscript = [NSStringstringWithFormat:@"%@my_post(\"%@\", %@);",POST_JS, urlStr, jsonString];

5、执行js

[wkWebView evaluateJavaScript:jscript completionHandler:nil];

到这里基本实现完成了。

补充

上面实现中用到的函数

- (NSString*)jsonStringFromDictionary:(NSDictionary*)dcitionary

{

    NSError*error =nil;

    NSData*jsonData =nil;

    if(!self) {

        returnnil;

    }

    NSMutableDictionary *dict = [NSMutableDictionary dictionary];

    [dcitionaryenumerateKeysAndObjectsUsingBlock:^(id  _Nonnullkey,id  _Nonnullobj,BOOL*_Nonnullstop) {

        NSString*keyString =nil;

        NSString*valueString =nil;

        if ([key isKindOfClass:[NSString class]]) {

            keyString = key;

        }else{

            keyString = [NSStringstringWithFormat:@"%@",key];

        }

        if ([obj isKindOfClass:[NSString class]]) {

            valueString = obj;

        }else{

            valueString = [NSStringstringWithFormat:@"%@",obj];

        }

        [dictsetObject:valueStringforKey:keyString];

    }];

    jsonData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:&error];

    if([jsonDatalength] ==0|| error !=nil) {

        returnnil;

    }

    NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

    returnjsonString;

}

相关文章

网友评论

      本文标题:iOS--WKWebView加载Post请求丢失body的解决方

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