I want to do a POST request to my WKWebView
but the headers doesn't get set when I monitor the requests with Charles so the request fails. What is wrong here?
NSString *post = [NSString stringWithFormat: @"email=%@&password=%@", email, password]; NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; NSString *contentLength = [NSString stringWithFormat:@"%d", postData.length]; NSURL *url = [NSURL URLWithString:@"http://materik.me/endpoint"]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; [request setHTTPMethod:@"POST"]; [request setHTTPBody:postData]; [request setValue:contentLength forHTTPHeaderField:@"Content-Length"]; [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; [webview loadRequest:request];
And this is what Charles says the request is like:
POST /endpoint HTTP/1.1 Host: materik.me Content-Type: application/x-www-form-urlencoded Origin: null Connection: keep-alive Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 User-Agent: Mozilla/5.0 (iPhone; CPU OS 8_0 like Mac OS X) Content-Length: 0 Accept-Language: en-us Accept-Encoding: gzip, deflate
So, as you can see, Content-Length
is 0
, Accept
is not application/json
and no request body were sent.
Thanks for any help.
Since then, we've recommended that you adopt WKWebView instead of UIWebView and WebView — both of which were formally deprecated. New apps containing these frameworks are no longer accepted by the App Store.
The WKWebView already contains a scrollview. All you need to do is create the refresh control, assign a target function that will get called when a user initiates a refresh, and attach the refresh control to the scrollview.
To clear old contents of webview With UIWebView you would use UIWebViewDelegate 's - webViewDidFinishLoad: .
As the OP stated, I have also confirmed in Charles that the body is 0 bytes after webView.load(request)
.
There's a workaround for this WKWebView
bug, we will initiate a POST
request using URLSession convert the data returned by the server to String
and instead of loading the url we will use loadHTMLString which will:
Set the webpage contents and base URL.
and the content is our converted string:
var request = URLRequest(url: URL(string: "http://www.yourWebsite")!) request.httpMethod = "POST" let params = "do=something&andAgain=something" request.httpBody = params.data(using: .utf8) let task = URLSession.shared.dataTask(with: request) { (data : Data?, response : URLResponse?, error : Error?) in if data != nil { if let returnString = String(data: data!, encoding: .utf8) { self.webView.loadHTMLString(returnString, baseURL: URL(string: "http://www.yourWebsite.com")!) } } } task.resume()
I had the same problem with WKWebView, that I decided to use instead of UIWebView to avoid the pickers crash in iOS 8. There are two ways that I can think of:
connection:didReceiveData:
and connectionDidFinishLoading:
from the delegate if you don't use a self signed SSL certificate)Create file eg. "POSTRequestJS.html":
<html> <head> <script> //POST request example: //post('URL', {key: 'value'}); function post(path, params) { var method = "post"; var form = document.createElement("form"); form.setAttribute("method", method); form.setAttribute("action", path); for(var key in params) { if(params.hasOwnProperty(key)) { var hiddenField = document.createElement("input"); hiddenField.setAttribute("type", "hidden"); hiddenField.setAttribute("name", key); hiddenField.setAttribute("value", params[key]); form.appendChild(hiddenField); } } document.body.appendChild(form); form.submit(); } </script> </head> <body> </body> </html>
And in your code after where you want to load your request:
NSString *path = [[NSBundle mainBundle] pathForResource:@"POSTRequestJS" ofType:@"html"]; NSString *html = [[NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil]; WKWebView.navigationDelegate = self; [WKWebView loadHTMLString:html baseURL:[[NSBundle mainBundle] bundleURL]];
Add method:
- (void)makePostRequest { NSString *postData = [NSString stringWithFormat: @"email=%@&password=%@", email, password]; NSString *urlString = @"http://materik.me/endpoint"; NSString *jscript = [NSString stringWithFormat:@"post('%@', {%@});", urlString, postData]; DLog(@"Javascript: %@", jscript); [WKWebView evaluateJavaScript:jscript completionHandler:nil]; didMakePostRequest = YES; }
And last add the WKNavigationDelegate:
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { if (!didMakePostRequest) { [self makePostRequest]; } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With