My best guess as to what is happening is that your parameters are slightly off, e.g. the app hasn’t been granted permission yet. The server is responding with an error page, but that error page doesn’t have the CORS headers. I’ve seen this before in a few other places where the server responds with generic error pages that don’t have CORS headers though successful requests will.
However, this may be intentional in this case.
You should not be doing code-based OAuth token-exchange from the browser. The browser isn’t a secure environment in general because it’s running on an untrusted machine in most cases. You should only use implicit grant so that the browser doesn’t store the long-lived refresh token. It’s not surprising that those pages were never designed to be called asynchronously from the browser.
oauth_authorize you should be request
response_type=token instead of using
response_type=code. You then won’t have to go through the extra step of exchanging the code for a token. The client library should handle this with an option somewhere.