My application uses POST requests with CORS for backend services (from www.mydomain.com
to api.mydomain.com
). The backend is served by a Tomact8 server, implementing a CORSResponseFilter
as shown below:
public class CORSResponseFilter implements ContainerResponseFilter {
public void filter( ContainerRequestContext requestContext, ContainerResponseContext responseContext ) throws IOException {
MultivaluedMap< String, Object > headers = responseContext.getHeaders();
headers.add( "Access-Control-Allow-Origin", "*" );
headers.add( "Access-Control-Allow-Methods", "POST" );
headers.add( "Access-Control-Allow-Headers", "X-Requested-With, Content-Type" );
}
}
While everything is functioning smoothly, Chrome on iOS seems to be an exception (Chrome on Android works fine!). For this specific client, Tomcat appears to be refusing to respond to the pre-flight OPTIONS
request. The Tomcat access log snippet below showcases this:
10.10.10.9 - - [14/Sep/2015:20:55:45 +0200] "OPTIONS /api HTTP/1.1" 200 - "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) CriOS/45.0.2454.68 Mobile/13B5110e Safari/600.1.4"
10.10.10.1 - - [14/Sep/2015:20:56:29 +0200] "OPTIONS /api HTTP/1.1" 200 561 "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36"
The discrepancy in response size between these two requests is noticeable, indicating a potential issue with the initial request not receiving a proper response for Chrome on iOS.
Debugging Chrome on iOS using weinre reveals that while the POST
request initiates, it never receives a response (even though Tomcat only receives an OPTIONS
request and no subsequent POST
).
On the client side, HTTP calls are made using the superagent
library. It remains unclear whether the problem stems from the Tomcat server or the client/browser, as it solely affects a particular device/browser combination (Chrome on iOS).
Has anyone encountered similar behavior and can offer insight into what may be missing?
PS: Despite the iPhone running a pre-release iOS version, the issue persists with regular iOS versions as well.
UPDATE: Utilizing WireShark, I've compared the headers from the OPTIONS
request on both desktop and mobile platforms.
From CriOS:
Connection: keep-alive
Access-Control-Request-Headers: accept, origin, content-type
Access-Control-Request-Method: POST
Accept: */*,image/webp
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) CriOS/45.0.2454.89 Mobile/13B5110e Safari/600.1.4
Accept-Encoding: gzip, deflate, sdch
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
From desktop:
Connection: keep-alive
Access-Control-Request-Method: POST
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36
Access-Control-Request-Headers: accept, content-type
Accept: */*
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,de-DE;q=0.6,de;q=0.4,ru;q=0.2
One observation is the presence of the image/webp media type in the ACCEPT
header, alongside */*. It's uncertain if this detail is significant...