我正在寻找一种以编程方式动态更改navigator.userAgent的方法.在我尝试获得自动javascript单元测试器失败的尝试中,我放弃并试图开始使用fireunit.我立即猛烈抨击了使用实际浏览器进行javascript测试的一面墙.
具体来说,我需要更改navigator.userAgent来模拟几百个userAgent字符串,以确保对给定函数的正确检测和覆盖.navigator.userAgent只读,所以我好像卡住了!我怎么能模拟navigator.userAgent?用户代理切换器(插件)可以切换FF的useragent,但我可以在javascript中执行吗?
尝试:
navigator.__defineGetter__('userAgent', function(){ return 'foo' // customized user agent }); navigator.userAgent; // 'foo'
在FF2和FF3中尝试过.
添加到Crescent Fresh的解决方案,重新定义navigator.userAgent
getter似乎在Safari 5.0.5中不起作用(在Windows 7和Mac OS X 10.6.7上).
需要创建一个从对象继承的新对象,navigator
并定义一个新的userAgent
getter来隐藏原始的userAgent
getter navigator
:
var __originalNavigator = navigator; navigator = new Object(); navigator.__proto__ = __originalNavigator; navigator.__defineGetter__('userAgent', function () { return 'Custom'; });
以下解决方案适用于Chrome,Firefox,Safari,IE9 +以及iframe:
function setUserAgent(window, userAgent) { if (window.navigator.userAgent != userAgent) { var userAgentProp = { get: function () { return userAgent; } }; try { Object.defineProperty(window.navigator, 'userAgent', userAgentProp); } catch (e) { window.navigator = Object.create(navigator, { userAgent: userAgentProp }); } } }
例子:
setUserAgent(window, 'new user agent'); setUserAgent(document.querySelector('iframe').contentWindow, 'new user agent');
使用Object.defineProperty应该添加几个浏览器:
if (navigator.__defineGetter__) { navigator.__defineGetter__("userAgent", function () { return "ua"; }); } else if (Object.defineProperty) { Object.defineProperty(navigator, "userAgent", { get: function () { return "ua"; } }); }
此代码应该工作(和测试)的火狐1.5 +,Chrome浏览器6+,歌剧10.5+和IE9 +.不幸的是,任何平台上的Safari都不允许更改userAgent.
编辑:Safari不允许更改userAgent,但可以替换整个导航器对象,如上面的另一个解决方案所述.