Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

react native webview ios: should I intercept ajax request, and set headers of the request?

I use react native's webview component, the situation is that I want to intercept ajax request, and set custom headers of the request, such as User-Agent, Referer, Cooike and so on, is there any solutions?

like image 246
user4843115 Avatar asked Sep 02 '25 02:09

user4843115


1 Answers

I have the same problem where I am wrapping an 3rd party web in React Native webview and in my case I needed to add Authorization header to every XHR (ajax) request.

One hack I came up with was to inject javascript into the webview that modifies prototype of XMLHttpRequest.open to intercept all requests from inside the web view.

We did not end up using this, but during testing it actually did work. I did not test this in Android but can't see why it should not work.

Here is a snippet from the POC that describes what I mean:

render() {
    const accessTokenInterceptor = this.buildAccessTokenInterceptorInjection(this.state.accessToken, "api.example.com");

    return (
        <WebView
            injectedJavaScript={accessTokenInterceptor}
            javaScriptEnabled={true}
            source={{
                uri: 'https://example.com'
            }}
        />
    );  
}

/**
 * This name might require an explanation :)
 *
 * AFAIK there is no simple way of intercepting XHR requests that are being made
 * from within the webview.
 *
 * A way to deal with this is to inject a script into the webview that modifies
 * XMLHttpRequest.prototype.open so that everytime it is invoked a headers is added.
 *
 * Yes, this is a hack - if you find any better solution, I'll buy you a beer!
 *
 */
buildAccessTokenInterceptorInjection(accessToken, whitelistedDomain) {
    return `
        (function() {
            XMLHttpRequest.prototype.realOpen = XMLHttpRequest.prototype.open;

            var openWithAccessToken = function(method, url, async, user, password) {
                this.realOpen(method, url, async, user, password);

                if (url.indexOf('${whitelistedDomain}') > 0) {
                    this.setRequestHeader('Authorization', 'Bearer ${accessToken}');
                }
            }

            XMLHttpRequest.prototype.open = openWithAccessToken;
        })()
    `;
}
like image 178
Joel S Avatar answered Sep 06 '25 00:09

Joel S