Pregunta

Estoy buscando una manera de cambiar mediante programación navigator.userAgent sobre la marcha. En mi intento fallido de conseguir un probador de unidad de JavaScript automatizado, me di por vencido y trató de comenzar a utilizar fireunit. Inmediatamente, he estrelló contra una de las paredes de la utilización de un navegador real para pruebas de JavaScript.

En concreto, tengo que cambiar navigator.userAgent para simular unos pocos cientos de cadenas de agente de usuario para garantizar la detección y la cobertura adecuada en una determinada función. navigator.userAgent es de sólo lectura, por lo que parece atascado! ¿Cómo puedo burlarse navigator.userAgent? User Agent Switcher (plug-in) puede cambiar de agente de usuario FF, pero puedo hacerlo en javascript?

¿Fue útil?

Solución

Probar:

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

navigator.userAgent; // 'foo'

probado en FF2 y FF3.

Otros consejos

Adición a solución de Media Luna Fresh , redefiniendo el getter navigator.userAgent no parece trabajar en Safari 5.0.5 (en Windows 7 y Mac OS X 10.6.7).

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

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

La siguiente solución funciona en Chrome, Firefox, Safari, IE9 + y también con marcos flotantes:

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

El uso de Object.defineProperty debe añadir varias más navegadores 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 debe trabajar (y fue probado) en Firefox 1.5 + , Chrome 6 + , Opera 10.5 + y IE9 + . Desafortunadamente Safari en cualquier plataforma no permite cambiar el userAgent.

Edit:. Safari no permite el cambio de la userAgent, pero uno puede sustituir la totalidad navegador objeto, como se ha señalado en otra solución anterior

La respuesta de la Media Luna fresco es correcta. Pero hay un problema: __defineGetter__ está en desuso:

https: //developer.mozilla. org / es-eS / docs / web / JavaScript / Referencia / Global_Objects / objeto / defineGetter

  

Desaprobados   Esta característica se ha eliminado de los estándares Web.   Aunque algunos navegadores pueden todavía apoyarlo, es en el proceso de   que se cayó. No lo utilice en proyectos viejos o nuevos. Páginas o aplicaciones web   el uso que puede romperse en cualquier momento.

Debe utilizar defineProperty lugar:

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

navigator.userAgent; // 'foo'

Para actualizar este hilo, defineGetter ya no funciona en jazmín, ya que está desfasada. Sin embargo, me encontré con esto me permite modificar el captador de navigator.userAgent de jazmín:

navigator = {
  get userAgent() {
    return 'agent';
  }
}

console.log(navigator.userAgent); // returns 'agent'

Sólo recuerde restablecer el navegador de objetos, una vez que haya terminado la prueba en el jazmín

Para aquellos que tratan de hacer lo mismo a máquina de escribir aquí está la solución:

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

navigator.userAgent; // 'foo'

O lo mismo para el idioma:

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

Creo que me gustaría tener un enfoque de inyección de dependencia. En lugar de:

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

Tal vez hacer 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);
}

A continuación, puede "burlarse cabo" getUserAgent() haciendo:

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

function getUserAgent() { // formerly 'Mock'
    // ...
}

Este diseño aún no está completamente automatizado (usted tiene que cambiar manualmente el nombre del comprador para llevar a cabo sus pruebas), y se añade un montón de complejidad a algo tan simple como operar en navigator.userAgent, y no estoy seguro de cómo se' d realidad identificar cualquier error en myFunction, pero yo sólo pensé en tirar por ahí para darle algunas ideas de cómo esto podría ser tratado.

Tal vez la idea de "inyección de dependencias" que aquí se presenta alguna manera puede ser integrado con FireUnit.

Para los que están aquí porque tienen que cambiar el valor userAgent en las pruebas de unidad, la solución de Tyler largo funciona, pero si desea restaurar la userAgent inicial o cambiar más de una vez, es probable que tenga que configurar la propiedad como configurable:

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

De lo contrario, podría encontrarse con un error de TypeError: Cannot redefine property. A mí me funciona en Chrome sin cabeza.

navigator.userAgent es una propiedad de cadena de sólo lectura, así que no es posible editarlo

Por encima de respuestas no estaban trabajando para PhantomJS + mecanografiado. A continuación el código que funcionó para mí:

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

tarde a este tema, pero por Karma + Jasmin y Letra de imprenta y desea establecer la propiedad userAgent esto hará que:

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

});

Este artículo le ayudó: https://www.codeproject.com / Consejos / 1036762 / imita-userAgent-con-JavaScript

Cambiar 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 se trabaja en el control de navegador web Internet Explorer, puede hacer doble parodia HTTP solicitud y JavaScript navigator.userAgent través 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

No, no creo que se puede hacer dentro de Javascript. Pero con Firefox Conmutador de agente de usuario puede probar cualquier agente de usuario que desea, ¿por qué no sólo tiene que utilizar eso?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top