Frage

Ich bin auf der Suche nach einem Weg, um programm navigator.userAgent on the fly zu ändern. In meinem gescheiterten Versuch, einen automatisierten Javascript Einheit Tester zu bekommen, gab ich auf und versuchte mit fireunit zu beginnen. Sofort habe ich knallte in eine der Wände für Javascript-Test einen aktuellen Browser zu verwenden.

Insbesondere muss ich navigator.userAgent ändern ein paar hundert Useragent-Strings simulieren auf einer bestimmten Funktion einwandfreie Erkennung und Abdeckung zu gewährleisten. navigator.userAgent ist nur lesbar, so scheine ich fest! Wie kann ich navigator.userAgent verspotten? User Agent Switcher (Plugin) kann wechseln FF User-Agent, aber kann ich es in Javascript?

War es hilfreich?

Lösung

Versuchen:

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

navigator.userAgent; // 'foo'

Versucht es in FF2 und FF3.

Andere Tipps

Hinzufügen auf Crescent Frische Lösung , die navigator.userAgent Getter neu definiert scheint nicht in Safari 5.0.5 (auf Windows 7 und Mac OS X 10.6.7) zu arbeiten.

Sie möchten ein neues Objekt erstellen, die von dem navigator Objekt erbt und definiert einen neuen userAgent Getter den ursprünglich userAgent Getter in navigator zu verbergen:

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

Die folgende Lösung funktioniert in Chrome, Firefox, Safari, Internet Explorer 9 + und auch mit 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
            });
        }
    }
}

Beispiele:

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

Object.defineProperty verwenden sollte mehr Browser zu der Mischung hinzufügen:

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

sollten Dieser Code funktioniert (und getestet) in Firefox 1.5 + , Chrome 6 + , Opera 10.5 + und IE9 + . Leider erlaubt es Safari auf jeder Plattform nicht den Useragenten ändern.

Edit:. Safari ist nicht der Useragent ändern, aber man kann die ganze Navigator Objekt, wie erwähnt in einer anderen Lösung oben ersetzen

Crescent Frische Antwort ist richtig. Aber es gibt ein Problem: __defineGetter__ veraltet ist:

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

  

Veraltet   Diese Funktion wurde von den Web-Standards entfernt.   Obwohl einige Browser es noch unterstützen kann, ist es im Prozess der   fallen gelassen. Verwenden Sie es nicht in alten oder neuen Projekten verwenden. Seiten oder Web-Anwendungen   indem sie jederzeit brechen kann.

Sie sollten verwenden defineProperty statt:

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

navigator.userAgent; // 'foo'

diesen Thread zu aktualisieren, wird defineGetter nicht mehr in Jasmine arbeiten, wie es aufgegeben. Allerdings fand ich dies ermöglicht es mir, die Getter für navigator.userAgent in Jasmin zu ändern:

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

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

Denken Sie daran, den Navigator Objekt zurückzusetzen, wenn Sie in Jasmin Testen fertig sind,

Für diejenigen, die versuchen, die gleiche Sache in Typoskript zu tun, hier ist die Lösung:

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

navigator.userAgent; // 'foo'

oder gleiche Sache für die Sprache aus:

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

Ich glaube, ich hätte gerne ein Dependency Injection-Ansatz. Statt:

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

Vielleicht so etwas wie:

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

Dann können Sie "verspotten" getUserAgent(), indem Sie:

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

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

Dieser Entwurf ist noch nicht vollständig automatisiert (Sie müssen manuell den Getter benennen Sie die Tests durchführen), und es fügt eine Reihe von Komplexität zu etwas so einfach wie auf navigator.userAgent arbeiten, und ich bin nicht sicher, wie Sie‘ tatsächlich identifizieren d irgendwelche Fehler in myFunction, aber ich dachte nur ich es werfen würde da draußen einige Ideen zu geben, wie dies könnte behandelt werden.

Vielleicht hier präsentierte die Idee der „Dependency Injection“ kann irgendwie mit FireUnit integriert werden.

Für hier diejenigen, weil sie brauchen den Useragent-Wert in Unit-Tests zu ändern, arbeitet Tyler Long Lösung, aber wenn Sie den anfänglichen Useragenten wiederherstellen mögen oder es mehr ändern als einmal, müssen Sie wahrscheinlich die Eigenschaft als konfigurierbar einzustellen:

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

Ansonsten könnten Sie in einen TypeError: Cannot redefine property Fehler ausgeführt. Funktioniert bei mir auf Chrome Headless.

navigator.userAgent ist eine schreibgeschützte String-Eigenschaft, so dass sie nicht möglich, sie bearbeiten

Vor Antworten funktioniert nicht für PhantomJS + Typoskript. Im Folgenden Code arbeitete für mich:

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

Späte zu diesem Thema, aber für Karma + Jasmin und Typoskript und wollen die Useragent-Eigenschaft festlegen diese es tun:

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

});

Dieser Artikel geholfen: https://www.codeproject.com / Tipps / 1036762 / Mocking-Useragent-with-JavaScript

Ändern navigator.userAgent auf Firefox und Opera über defineGetter

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

alert( navigator.userAgent ); //iPhone 5

Ändern navigator.userAgent auf IE und Opera über Objektinstanz

var navigator = new Object; 
navigator.userAgent = 'iPhone 5';

alert( navigator.userAgent ); //iPhone5

Gute Sache ist, wenn Sie auf IE-WebBrowser-Steuerelement arbeiten, können Sie Spoof sowohl HTTP-Anfrage und JavaScript navigator.userAgent über execScript

verdoppeln
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

Nein, ich bezweifle, dass Sie es in Javascript tun. Aber mit Firefox User Agent Switcher können Sie testen, was User-Agent Sie wollen, warum also nicht nur das benutzen?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top