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.
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:
andconnectionDidFinishLoading:
from the delegate if you don't use a self signed SSL certificate)Create file eg. "POSTRequestJS.html":
And in your code after where you want to load your request:
Add method:
And last add the WKNavigationDelegate:
Swift3
Change the
baseurl
andtoken
to your needs.This appears to be a bug.
https://bugs.webkit.org/show_bug.cgi?id=140188
Hopefully it will be addressed soon. In the meantime, reverting to UIWebView or implementing the workaround proposed by Spas Bilyarski in his answer seems to be the best options.
workaround: trick by using html5 & javascript.
Add a html5 file with content below to your xcode project. To post data by using javascript & h5 form:
Load the h5 file to WKWebView:
Prepare the parameters to post. ie. a string & an array of dictionary Note: when turn array to json string by using NSJSONSerialization, '\r' may be added automaticly. You must remove all the '\r' in the json string, or the javascript cannot be parsed correctly.
Put this in the WKWebView's delegate:
didFinishNavigation
WKWebView.load
method doesn't work with post request with post body. You have to use JavaScript to do the trick, checkWKWebView.evaluateJavascript
.It maybe a bug, but Apple hasn't addressed it till now.
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 aPOST
request using URLSession convert the data returned by the server toString
and instead of loading the url we will use loadHTMLString which will:and the content is our converted string: