惩戒在javascript中的UserAgent?
-
19-09-2019 - |
题
我正在寻找一种方法以编程方式动态更改navigator.userAgent的。在我失败的尝试得到一个自动的JavaScript单元测试,我放弃了,并试图开始使用fireunit。随即,我已经撞上使用实际的浏览器为JavaScript测试的壁中的一个。
具体来说,我需要改变的navigator.userAgent模拟几百的userAgent字符串,以确保在一个给定函数正确检测和覆盖范围。 navigator.userAgent的是只读的,所以我似乎卡住了!我怎么能嘲笑navigator.userAgent的?用户代理切换器(插件)可以切换FF的用户代理,但我可以做到这一点的JavaScript内?
解决方案
尝试:
navigator.__defineGetter__('userAgent', function(){
return 'foo' // customized user agent
});
navigator.userAgent; // 'foo'
试图在FF2和FF3。
其他提示
添加到新月新鲜的溶液时,重新定义navigator.userAgent
吸气剂似乎不工作在Safari 5.0.5(在Windows 7和Mac OS X 10.6.7)。
需要创建一个新对象从navigator
对象继承并定义一个新userAgent
吸气隐藏在userAgent
原始navigator
吸气剂:
var __originalNavigator = navigator;
navigator = new Object();
navigator.__proto__ = __originalNavigator;
navigator.__defineGetter__('userAgent', function () { return 'Custom'; });
下面的解决方案适用于浏览器,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 + 强>,<强>铬6 + 下,的歌剧10.5 + 和<强> IE9 + 即可。不幸的是Safari浏览器在任何平台上不允许更改的userAgent。
编辑:Safari浏览器不允许更改的userAgent,但可以替换整个的导航强>对象,如在上述的另一解决方案指出
新月新鲜的答案是正确的。但有一个问题:__defineGetter__
被弃用:
HTTPS://developer.mozilla。组织/ EN-US /文档/网络/的JavaScript /参考/ Global_Objects /对象/ defineGetter
<强>已过时强> 此功能已被从Web标准中删除。 尽管一些浏览器可能仍然支持它,它是在过程 被丢弃。不要在旧的或新的项目中使用它。网页或Web应用程序 使用它可以在任何时间中断。
您应该使用defineProperty
代替:
Object.defineProperty(navigator, "userAgent", {
get: function () {
return "foo"; // customized user agent
}
});
navigator.userAgent; // 'foo'
要更新这个帖子,defineGetter不会再在茉莉花,因为它是不推荐使用。然而,我发现这个允许我修改吸气为navigator.userAgent的在茉莉:
navigator = {
get userAgent() {
return 'agent';
}
}
console.log(navigator.userAgent); // returns 'agent'
只要记住重置导航对象一旦你完成在茉莉测试
对于那些试图做同样的事情在打字稿这里的解决方案:
(<any>navigator)['__defineGetter__']('userAgent', function(){
return 'foo';
});
navigator.userAgent; // 'foo'
或者语言一样的东西:
(<any>navigator)['__defineGetter__']('language', function(){
return 'de-DE';
});
我想我需要依赖注入的方法。代替:
function myFunction() {
var userAgent = navigator.userAgent;
// do stuff with userAgent
}
也许这样做:
function myFunction(userAgent) {
// do stuff with userAgent
}
function getUserAgent() {
window.userAgentReal = +window.userAgentReal || 0;
return [ navigator.userAgent ][window.userAgentReal++];
}
function getUserAgentMock() {
window.nextUserAgentMock = +window.nextUserAgentMock || 0;
return [
'test user agent1',
'test user agent2',
'test user agent3'
][window.nextUserAgentMock++];
}
var userAgent;
while (userAgent = getUserAgent()) {
myFunction(userAgent);
}
然后可以通过执行 “模拟出” getUserAgent()
:
function getUserAgentReal() { // formerly not 'Real'
// ...
}
function getUserAgent() { // formerly 'Mock'
// ...
}
此设计还没有完全自动化(您必须手动重命名为您进行测试的getter),并增加了一堆复杂的,以作为navigator.userAgent
操作简单的东西,我不知道你怎么” ð实际上识别myFunction
任何错误,但我只是想我会扔在那里给你一些想法如何,这可能与处理。
也许“依赖注入”这里提出的思想可以以某种方式与FireUnit集成。
对于那些在这里,因为他们需要改变在单元测试中的userAgent值,泰勒长期的解决方案的工作,但如果你想恢复到初始的userAgent或改变不止一次,你可能需要的属性设置为配置:
function setUserAgent(userAgent) {
Object.defineProperty(navigator, "userAgent", {
get: function () {
return userAgent; // customized user agent
},
configurable: true
});
}
// Now in your setup phase:
// Keep the initial value
var initialUserAgent = navigator.userAgent;
setUserAgent('foo');
// In your tearDown:
// Restore the initial value
setUserAgent(initialUserAgent);
否则,你可能会遇到一个TypeError: Cannot redefine property
错误。
适用于我在Chrome无头。
navigator.userAgent
是只读字符串属性,所以它无法修改它
以上答案没有工作PhantomJS +打字稿。下面的代码为我工作:
var __originalNavigator = navigator;
(window as any).navigator = new Object();
navigator["__proto__"] = __originalNavigator["__proto__"];
navigator["__defineGetter__"]('userAgent', function () { return 'Custom'; });
下旬到这个话题但噶+茉莉和打字稿,并要设置userAgent属性,这将做到这一点:
describe('should validate YYYY-MM-dd format only on IE browser', () => {
// this validator has a specific condition to work only in IE11 and down
(window as any).navigator.__defineGetter__('userAgent', function () {
return 'MSIE';
});
...
// rest of the test
});
此文章帮助: https://www.codeproject.com /提示/ 1036762 /嘲讽-的userAgent-与JavaScript的
更改navigator.userAgent的上Firefox和Opera经由defineGetter
navigator.__defineGetter__('userAgent', function(){
return( "iPhone 5" );
});
alert( navigator.userAgent ); //iPhone 5
更改navigator.userAgent的上IE和Opera经由对象实例
var navigator = new Object;
navigator.userAgent = 'iPhone 5';
alert( navigator.userAgent ); //iPhone5
的好处是,如果在IE浏览器控件,则可以增加一倍欺骗两者的HTTP请求,并经由EXECSCRIPT的JavaScript navigator.userAgent的
WebBrowser1.Navigate "http://example.com", , , , "User-Agent: iPhone 5" & vbCrLf
WebBrowser1.Document.parentWindow.execScript ("var navigator=new Object;navigator.userAgent='iPhone 5';")
WebBrowser1.Document.parentWindow.execScript ("alert(navigator.userAgent);") 'iPhone 5
没有,我怀疑你可以在JavaScript中做到这一点。但随着Firefox的用户代理切换器可以测试任何你想要的用户代理,所以为什么不使用呢?