setting useragent of iframe via javascript

2019-05-27 02:47发布

问题:

Business requirement trying to be met: Loading an existing page within an iframe, emulating an iphones user agent. The reason this needs to happen client side, is that there are client side scripts which detect the user agent and appends some classes onto the html element. Based on this the style of the site will radically change as the CSS targets elements based on the html classes.

So it would take and turn it into or in the case that I'm trying to resolve here etc.

Using window.open works (as demonstrated in this code) within chrome. The site renders with the proper mobile styling.

Using the iframe works, but only in FF.

Ideally, I'd like to have the iframe version working within Chrome and FF.

Any thoughts?

<script type="text/javascript">


        navigator.__defineGetter__('userAgent', function () {
            return 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_2 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8H7 Safari/6533.18.5';
        });

        var win = window.open('/home/get');
        win.navigator.__defineGetter__('userAgent', function () {
            return 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_2 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8H7 Safari/6533.18.5';
        });
        win.location.href = '/home/get'; //required


        $(function () {
            var frame = $('<iframe width="320" height="480"></iframe>');
            frame.hide();
            $('#container').append(frame);


            (frame[0].contentWindow || frame[0].contentDocument).navigator.__defineGetter__('userAgent', function () {
                return 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_2 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8H7 Safari/6533.18.5';
            });
            frame.attr('src', '/home/get');

            });


            frame.fadeIn();
        });
    </script>

回答1:

Figured it out, works for FF, Chrome and IE. I'm not sure about Safari as I don't have it installed. The synopsis of it is to make an ajax request, fetch the html and then open up the iframes document. AFTER you open it, then you override its userAgent getter and then write the html you received from the ajax call.

        $(function () {
        var frame = $('<iframe width="320" height="480"></iframe>');
        frame.hide();

        $('#container').append(frame);
        var contentWindow = frame[0].contentWindow || frame[0].contentDocument;

        var setUA = function() {
            if (Object.defineProperty) {
                Object.defineProperty(contentWindow.navigator, 'userAgent', {
                    configurable: true,
                    get: function () {
                        return 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_2 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8H7 Safari/6533.18.5';
                    }
                });
            } else if (Object.prototype.__defineGetter__) {
                contentWindow.navigator.__defineGetter__('userAgent', function () {
                    return 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_2 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8H7 Safari/6533.18.5';
                });
            } else {
                alert('browser not supported');
            }
        };

        $.ajax({
            cache: false,
            url: '/home/get',
            success: function (html) {
                contentWindow.document.open();
                setUA();
                contentWindow.document.write(html);
                contentWindow.document.close();
                frame.fadeIn();
            }
        });
    });


回答2:

You cannot do anything like this with an iframe. The user agent is sent with the headers on the initial request.

Alternatives:

Use a backend proxy. The iframe actually is loading the page from your own server, which is loading the remote page via a proxy. You can set whatever header you want then. This really only works if the 3rd party site doesn't require a login, because you don't want to be proxying a user's session.

If the remote site supports CORS, you can do an XHR request from your page that sets a user agent header and gets back the contents of the page. You could then add that code into the iframe. Beware of severe security issues with this technique.

My recommendation, come up with a different plan of action.