I'd like to intercept XHR requests for the Google Maps API so I can run them through my own proxy server as a way of keeping my API key private.
Angular has its own HttpInterceptor
s, but they'll only intercept XHR requests which are made using Angular's HttpClient
, not any requests made outside of the Angular framework by the Maps API. I'd think that monkey patching XMLHttpRequest.open()
would be the best way to get at the requests going to the Maps API, which I've done like this:
var oldXHROpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url, async, username, password) {
console.log(url);
return oldXHROpen.apply(this, arguments);
};
The above code is placed in a <script>
in the <head>
section of my index.html
, so it's definitely executed before any Angular code is executed.
The patch works... for a short time. I see URLs for a few assets loaded by my code logged out, but then this message appears:
Angular is running in the development mode. Call enableProdMode() to enable the production mode.
After that just one more URL gets logged, and that's the last intercept I make. XHR requests continue to be processed, but my patch never sees them happen.
I'm sure this has something to do with zone.js, but I still don't understand how it could happen. Since I redefine XMLHttpRequest.prototype.open
before Angular or zone.js even get a chance to see the original open()
function, which is tucked away in the oldXHROpen
variable, how does a direct connection to the native open()
ever manage to happen again, bypassing my patch?
It appears I was laboring under the false premise that the client side of the Google Maps API would have to make XHR requests to get its work done.
It doesn't. It's all done by loading images, CSS, and fonts, with a little JSONP thrown in.
My monkey patching actually does work, and doesn't get undone by Angular.