WKWebView带Authorization头POST请求报500,后端未接收,求其他加载方式
问题分析与解决方案
你当前的POST请求代码存在两个关键问题:
- 声明了
Content-Type: application/x-www-form-urlencoded但未设置HTTPBody,不符合POST请求的规范; - WKWebView的
loadRequest:方法对无Body的POST请求处理存在限制,可能导致请求未被正确发送到后端。
以下是几种在WKWebView中携带Authorization头加载请求的可行方案:
方案1:HTML自动提交表单(最推荐)
模拟浏览器原生表单提交逻辑,WKWebView对这种方式的兼容性最好,能正常携带认证头和POST数据:
NSString *fullURL = _URL; NSString *token = [NSString stringWithFormat:@"bearer %@", [UserDefaults getAccessToken]]; // 构造自动提交的HTML页面,替换其中的POST参数为你的实际参数(无参数可移除对应部分) NSString *htmlContent = [NSString stringWithFormat:@"<!DOCTYPE html>" "<html>" "<body onload=\"document.getElementById('postForm').submit()\">" "<form id='postForm' method='POST' action='%@'>" "<input type='hidden' name='param1' value='value1'>" "</form>" "</body>" "</html>", fullURL]; // 加载HTML,指定基础URL为目标接口地址 [_webview loadHTMLString:htmlContent baseURL:[NSURL URLWithString:fullURL]]; // 额外:如果需要手动通过JS发送请求(更灵活),可以替换上面的HTML为以下内容 /* NSString *jsHtml = [NSString stringWithFormat:@"<!DOCTYPE html>" "<html>" "<script>" "window.onload = function() {" " let xhr = new XMLHttpRequest();" " xhr.open('POST', '%@', true);" " xhr.setRequestHeader('Authorization', '%@');" " xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');" " xhr.send('param1=value1');" " xhr.onload = function() { document.write(xhr.responseText); }" "};" "</script>" "</html>", fullURL, token]; [_webview loadHTMLString:jsHtml baseURL:[NSURL URLWithString:fullURL]]; */
方案2:通过WKNavigationDelegate拦截修改请求
给WKWebView设置代理,在请求发起前注入Authorization头,适用于全局处理所有请求(包括页面跳转):
首先设置代理:
_webview.navigationDelegate = self;
然后实现代理方法:
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { NSMutableURLRequest *modifiedReq = [navigationAction.request mutableCopy]; NSString *token = [NSString stringWithFormat:@"bearer %@", [UserDefaults getAccessToken]]; [modifiedReq setValue:token forHTTPHeaderField:@"Authorization"]; // 修复无Body的POST请求问题:强制设置空Body避免WKWebView忽略请求 if ([modifiedReq.HTTPMethod isEqualToString:@"POST"] && !modifiedReq.HTTPBody) { [modifiedReq setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; [modifiedReq setHTTPBody:[@"" dataUsingEncoding:NSUTF8StringEncoding]]; } // 取消原请求,加载修改后的请求 decisionHandler(WKNavigationActionPolicyCancel); [webView loadRequest:modifiedReq]; }
方案3:注入WKUserScript全局添加AJAX请求头
如果需要页面内的所有AJAX请求自动携带Authorization头,可通过用户脚本注入实现(仅影响JS发起的请求,不影响初始页面加载):
NSString *token = [UserDefaults getAccessToken]; NSString *scriptSource = [NSString stringWithFormat:@"Object.defineProperty(XMLHttpRequest.prototype, 'open', { " " value: function(method, url, async, user, password) { " " this.setRequestHeader('Authorization', 'bearer %@'); " " return XMLHttpRequest.prototype.open.apply(this, arguments); " " } " "});", token]; WKUserScript *authScript = [[WKUserScript alloc] initWithSource:scriptSource injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES]; WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init]; [config.userContentController addUserScript:authScript]; // 用配置初始化WKWebView WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:config];
内容的提问来源于stack exchange,提问作者knightwish
相关产品推荐
相关产品推荐

