What you are trying to do is out of spec, specifically including Access-Control-Allow-Credentials: true and Access-Control-Allow-Origin: * . Is not allowed and its not allowed <i>for a very good reason</i>. That being that it is completely insecure. This combination, when visiting a hostile site will allow that site to act with the users credentials without any feedback or action on the users part.<p>IE9's limitations are also in spec, and again its behavior is for a good reason. Specifically GET and POST don't need to be preflighted and so webapps need to be prepared for the case where a hostile post request comes from a disallowed referrer (which can't be manipulated through javascript). Other methods do need to be preflighted so browsers that are unable to do that are not allowed to send cross-origin PUT,DELETE, etc. In fact most of the "frustrating" things MS does (e.g. disallowing cross scheme AJAX) are well thought out and if you don't understand why they make sense there is a good chance that you are creating security vulnerabilities.
Quick suggestion: rather than having your headers return 'Access-Control-Allow-Origin' '*';, you're better off echoing the requesting domain back, so that in the future you'll be able to maintain a whitelist of registered domains. Prevents usage from any-old-domain (though I realize you have authorization already built into some parts of your API).
If you need more info on how to enable CORS try this:<p><a href="http://enable-cors.org" rel="nofollow">http://enable-cors.org</a><p>In this case<p><a href="http://enable-cors.org/server_nginx.html" rel="nofollow">http://enable-cors.org/server_nginx.html</a>
You could do it with <a href="https://apitools.com" rel="nofollow">https://apitools.com</a> instead of hosting ngx. Probably handling the origin case by case and even the authentication.