useragent objeto navegador detectar javascript unit-testing user-agent

objeto - Burlarse de un useragent en javascript?



navigator version javascript (12)

Añadiendo a la solución de Crescent Fresh , la redefinición del buscador navigator.userAgent no parece funcionar en Safari 5.0.5 (en Windows 7 y Mac OS X 10.6.7).

Necesidad de crear un nuevo objeto que herede del navigator y definir un nuevo userAgent para ocultar el userAgent original getter en el navigator :

var __originalNavigator = navigator; navigator = new Object(); navigator.__proto__ = __originalNavigator; navigator.__defineGetter__(''userAgent'', function () { return ''Custom''; });

Estoy buscando una forma de cambiar programáticamente navigator.userAgent sobre la marcha. En mi intento fallido de obtener un probador automático de unidades de JavaScript, me rendí e intenté comenzar a utilizar fireunit. Inmediatamente, he chocado contra una de las paredes de usar un navegador real para probar JavaScript.

Específicamente, necesito cambiar navigator.userAgent para simular unos cientos de cadenas de userAgent para asegurar una detección y cobertura adecuadas en una función determinada. navigator.userAgent es de solo lectura, ¡así que parece que estoy atascado! ¿Cómo puedo simular navigator.userAgent? User Agent Switcher (plugin) puede cambiar el uso de FF, pero ¿puedo hacerlo en javascript?


Cambie navigator.userAgent en Firefox y Opera a través de defineGetter

navigator.__defineGetter__(''userAgent'', function(){ return( "iPhone 5" ); }); alert( navigator.userAgent ); //iPhone 5

Cambiar navigator.userAgent en IE y Opera a través de instancia de objeto

var navigator = new Object; navigator.userAgent = ''iPhone 5''; alert( navigator.userAgent ); //iPhone5

Lo bueno es que si trabajas en el control del navegador web IE, puedes duplicar la suplantación tanto de la solicitud HTTP como de JavaScript navigator.userAgent a través de 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


El uso de Object.defineProperty debería agregar varios navegadores más a la mezcla:

if (navigator.__defineGetter__) { navigator.__defineGetter__("userAgent", function () { return "ua"; }); } else if (Object.defineProperty) { Object.defineProperty(navigator, "userAgent", { get: function () { return "ua"; } }); }

Este código debería funcionar (y fue probado) en Firefox 1.5+ , Chrome 6+ , Opera 10.5+ e IE9 + . Desafortunadamente, Safari en cualquier plataforma no permite cambiar el userAgent.

Editar: Safari no permite cambiar el userAgent, pero se puede reemplazar todo el navegador como se indicó en otra solución anterior.


La respuesta de Crescent Fresh es correcta. Pero hay un problema: __defineGetter__ está en desuso:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineGetter

Obsoleto Esta característica se ha eliminado de los estándares web. Aunque algunos navegadores aún pueden soportarlo, está en proceso de descarte. No lo use en proyectos antiguos o nuevos. Las páginas o aplicaciones web que lo usan pueden romperse en cualquier momento.

Deberías usar defineProperty en defineProperty lugar:

Object.defineProperty(navigator, "userAgent", { get: function () { return "foo"; // customized user agent } }); navigator.userAgent; // ''foo''


La siguiente solución funciona en Chrome, Firefox, Safari, IE9 + y también con 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 }); } } }

Ejemplos:

setUserAgent(window, ''new user agent''); setUserAgent(document.querySelector(''iframe'').contentWindow, ''new user agent'');


Las respuestas anteriores no funcionaban para PhantomJS + TypeScript. Debajo del código funcionó para mí:

var __originalNavigator = navigator; (window as any).navigator = new Object(); navigator["__proto__"] = __originalNavigator["__proto__"]; navigator["__defineGetter__"](''userAgent'', function () { return ''Custom''; });


No, dudo que puedas hacerlo dentro de javascript. Pero con User Agent Switcher de Firefox puede probar cualquier agente de uso que desee, entonces ¿por qué no usarlo?


Para actualizar este hilo, defineGetter ya no funciona en Jasmine ya que está en desuso. Sin embargo, encontré que esto me permite modificar el getter para navigator.userAgent en jazmín:

navigator = { get userAgent() { return ''agent''; } } console.log(navigator.userAgent); // returns ''agent''

Solo recuerda restablecer el navegador una vez que hayas terminado de probar en jazmín


Para aquellos que intentan hacer lo mismo en TypeScript, aquí está la solución:

(<any>navigator)[''__defineGetter__''](''userAgent'', function(){ return ''foo''; }); navigator.userAgent; // ''foo''

O lo mismo para el lenguaje:

(<any>navigator)[''__defineGetter__''](''language'', function(){ return ''de-DE''; });


Supongo que tomaría un enfoque de inyección de dependencia. En lugar de:

function myFunction() { var userAgent = navigator.userAgent; // do stuff with userAgent }

Tal vez haga algo como:

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); }

Entonces puedes "burlarse" de getUserAgent() haciendo:

function getUserAgentReal() { // formerly not ''Real'' // ... } function getUserAgent() { // formerly ''Mock'' // ... }

Este diseño aún no está completamente automatizado (hay que cambiar el nombre del getter manualmente para realizar las pruebas), y agrega complejidad a algo tan simple como operar en navigator.userAgent , y no estoy seguro de cómo lo haría. realmente identifica cualquier error en myFunction , pero pensé que lo lanzaría allí para darte algunas ideas de cómo se podría tratar esto.

Tal vez la idea de "inyección de dependencia" presentada aquí se pueda integrar de algún modo con FireUnit.


Tratar:

navigator.__defineGetter__(''userAgent'', function(){ return ''foo'' // customized user agent }); navigator.userAgent; // ''foo''

Intenté en FF2 y FF3.


navigator.userAgent es una propiedad de cadena de solo lectura, por lo que no es posible editarlo