I have an Ionic 2
application that calls a Spring Boot
API to send push notifications to other devices. The API is configured with HTTPS.
The API POST
request works on everything except iOS
.
My SSL certificate on the server is self signed (maybe that's it?).
Works on:
Here is the request:
public sendNotificationRequest(title: string, action: string, name: string, tokens: any, notifications: boolean) {
// Check if user turned off notifications
if(!notifications) {
return;
}
let headers = new Headers({'Content-Type': 'application/json'});
headers.append('Authorization', 'Basic ' + btoa(this.username_decrypted + ':' + this.password_decrypted));
let body = this.formObj(tokens, title, action, name);
console.log(body);
this.http.post("https://<some-url>",
body, { headers: headers }
).subscribe((response) => {
console.log("HTTPS RESPONSE");
console.log(response);
}, function(error) {
console.log("HTTPS ERROR");
console.log(error);
});
}
The header responses are as follows:
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
And the this error is received:
{
"_body":
{"isTrusted":true},
"status":0,"ok":false,
"statusText":"",
"headers":{},
"type":3,
"url":null
}
Spring Boot API:
@CrossOrigin
@RequestMapping(value="/notifications", method=RequestMethod.POST, consumes=MediaType.APPLICATION_JSON_VALUE, produces=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<NotificationParent> sendNotifications(@RequestBody NotificationParent objs) {
...
return new ResponseEntity<NotificationParent>(objs, HttpStatus.OK);
}
I am assuming its an iOS security issue, but I have no idea.
I had a same problem too. Removing the WkWebView solves the issue.
ionic cordova plugin remove cordova-plugin-wkwebview-engine
More info:
https://forum.ionicframework.com/t/ios10-http-requests-blocked/67663/2?u=profitsventure
After this plugin removed I can make http request via iOS
I think your assumption is correct-- an iOS security issue. In iOS there is something called App Transport Security that disallows, by default, connections over HTTP and connections with self-signed certificates.
You have to add
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
to the Info.plist
of your project to allow your self-signed traffic.
See this answer as well as the below links for more info.
http://blog.ionic.io/preparing-for-ios-9/
https://gist.github.com/mlynch/284699d676fe9ed0abfa
https://developer.apple.com/library/prerelease/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW33
For iOS devices, the default WebViewEngine always uses CORS, to disable it temporarily, add the <preference name="CordovaWebViewEngine" value="CDVUIWebViewEngine" />
to the config.xml
. However, the downgrading to UIWebViewEngine
has bad performance. Solving it in the server side is the right solution.
The HTTP server should be configured to have the right response to the CORS OPTIONS preflight request. The key point is that the Access-Control-Allow-Headers can not be “*” and should include any custom headers used in your app. Below is my setting that works:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: *
Access-Control-Allow-Headers: Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, MyCustomHeader
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