Se moquer d'un agent utilisateur en javascript?
je cherche un moyen de changer programmatiquement le navigateur.userAgent à la volée. Dans ma tentative ratée d'obtenir un testeur automatique d'unité javascript, j'ai abandonné et essayé de commencer à utiliser fireunit. Immédiatement, j'ai claqué dans l'un des murs de l'aide d'un navigateur pour le test javascript.
en particulier, je dois changer de navigateur.userAgent pour simuler quelques centaines de chaînes userAgent pour assurer une détection et une couverture adéquates sur une fonction donnée. Navigator.userAgent est en lecture seule, alors il me semble coincé! Comment puis-je me moquer de navigator?userAgent? User Agent Switcher (plugin) peut commuter L'useragent de FF, mais puis-je le faire dans javascript?
13 réponses
, Essayez:
navigator.__defineGetter__('userAgent', function(){
return 'foo' // customized user agent
});
navigator.userAgent; // 'foo'
a essayé en FF2 et FF3.
ajouté à solution de Crescent Fresh , redéfinissant le navigator.userAgent
getter ne semble pas fonctionner dans Safari 5.0.5 (sur Windows 7 & Mac OS X 10.6.7).
besoin de créer un nouvel objet qui hérite de l'objet navigator
et de définir un nouveau userAgent
getter pour cacher l'original userAgent
getter dans navigator
:
var __originalNavigator = navigator;
navigator = new Object();
navigator.__proto__ = __originalNavigator;
navigator.__defineGetter__('userAgent', function () { return 'Custom'; });
la solution suivante fonctionne en Chrome, Firefox, Safari, IE9+ et aussi avec iframes:
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
});
}
}
}
exemples:
setUserAgent(window, 'new user agent');
setUserAgent(document.querySelector('iframe').contentWindow, 'new user agent');
Utilisant L'Objet.defineProperty devrait ajouter plusieurs navigateurs supplémentaires à la composition:
if (navigator.__defineGetter__) {
navigator.__defineGetter__("userAgent", function () {
return "ua";
});
} else if (Object.defineProperty) {
Object.defineProperty(navigator, "userAgent", {
get: function () {
return "ua";
}
});
}
ce code devrait fonctionner (et a été testé) dans Firefox 1.5+ , Chrome 6+ , Opera 10.5+ et IE9+ . Malheureusement Safari sur n'importe quelle plate-forme ne permet pas de changer l'agent utilisateur.
Edit: Safari ne permet pas de changer l'userAgent, mais on peut remplacer le objet navigator entier, comme indiqué dans une autre solution ci-dessus.
la réponse de Crescent Fresh est correcte. Mais il y a un problème: __defineGetter__
est déprécié:
déprécié Cette fonctionnalité a été retirée des normes Web. Bien que certains navigateurs peuvent encore soutenir, il est dans le processus de être tomber. Ne l'utilisez pas dans des projets anciens ou nouveaux. Pages ou applications Web à l'aide, elle peut se briser à tout moment.
vous devez utiliser defineProperty
à la place:
Object.defineProperty(navigator, "userAgent", {
get: function () {
return "foo"; // customized user agent
}
});
navigator.userAgent; // 'foo'
pour mettre à jour ce fil, defineGetter ne fonctionne plus dans Jasmine car il a été déprécié. Cependant, j'ai trouvé que cela me permet de modifier le getter pour navigator.userAgent à jasmine:
navigator = {
get userAgent() {
return 'agent';
}
}
console.log(navigator.userAgent); // returns 'agent'
n'oubliez pas de réinitialiser l'objet navigator une fois que vous avez terminé les tests dans jasmine
pour ceux qui essaient de faire la même chose à la typographie voici la solution:
(<any>navigator)['__defineGetter__']('userAgent', function(){
return 'foo';
});
navigator.userAgent; // 'foo'
ou même chose pour la langue:
(<any>navigator)['__defineGetter__']('language', function(){
return 'de-DE';
});
je suppose que j'ai une approche d'injection de dépendance. Au lieu de:
function myFunction() {
var userAgent = navigator.userAgent;
// do stuff with userAgent
}
peut-être faire quelque chose comme:
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);
}
alors vous pouvez "mock out " getUserAgent()
en faisant:
function getUserAgentReal() { // formerly not 'Real'
// ...
}
function getUserAgent() { // formerly 'Mock'
// ...
}
cette conception n'est toujours pas complètement automatisée (vous devez renommer manuellement le getter pour effectuer vos tests), et il ajoute un tas de complexité à quelque chose d'aussi simple que l'exploitation sur navigator.userAgent
, et je ne suis pas sûr comment vous avez en fait identifié tous les bogues dans myFunction
, mais j'ai juste pensé que je voudrais le jeter là-bas pour vous donner quelques idées comment cela pourrait être traité.
peut-être que l'idée de "dependency injection" présentée ici peut être intégrée à FireUnit.
navigator.userAgent
est une propriété de chaîne de caractères en lecture seule, il n'est donc pas possible de l'éditer
ci-dessus les réponses ne fonctionnaient pas pour PhantomJS + TypeScript. Ci-dessous code travaillé pour moi:
var __originalNavigator = navigator;
(window as any).navigator = new Object();
navigator["__proto__"] = __originalNavigator["__proto__"];
navigator["__defineGetter__"]('userAgent', function () { return 'Custom'; });
en retard à ce sujet mais pour Karma + Jasmin et dactylographier et si vous voulez définir la propriété userAgent cela le fera:
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
});
cet article a aidé: https://www.codeproject.com/Tips/1036762/Mocking-userAgent-with-JavaScript
Non, Je doute que vous puissiez le faire avec javascript. Mais avec L'Agent utilisateur de Firefox Switcher vous pouvez tester n'importe quel agent utilisateur que vous voulez, alors pourquoi ne pas simplement utiliser cela?
Changer de navigateur.userAgent sur Firefox et Opera via defineGetter
navigator.__defineGetter__('userAgent', function(){
return( "iPhone 5" );
});
alert( navigator.userAgent ); //iPhone 5
Changer de navigateur.userAgent sur IE et Opera via l'instance de l'objet
var navigator = new Object;
navigator.userAgent = 'iPhone 5';
alert( navigator.userAgent ); //iPhone5
bonne chose est, si vous travaillez sur IE webbrowser contrôle, vous pouvez double spoof demande HTTP et JavaScript navigateur.userAgent via execScript
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