Подтвердить что ты не робот

Издевательствовать useragent в javascript?

Я ищу способ программно изменить navigator.userAgent на лету. В моей неудачной попытке получить автоматический тестер блока javascript я сдался и попытался начать использовать fireunit. Сразу же, я врезался в одну из стен, используя фактический браузер для тестирования javascript.

В частности, мне нужно изменить navigator.userAgent, чтобы смоделировать несколько сотен строк UserAgent, чтобы обеспечить надлежащее обнаружение и охват данной функции. navigator.userAgent только для чтения, поэтому я, похоже, застрял! Как я могу издеваться над navigator.userAgent? User Agent Switcher (плагин) может переключать Fag useragent, но могу ли я сделать это в javascript?

4b9b3361

Ответ 1

Try:

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

navigator.userAgent; // 'foo'

Пробовал его в FF2 и FF3.

Ответ 2

Добавление в решения Crescent Fresh, переопределение тэга navigator.userAgent, похоже, не работает в Safari 5.0.5 (в Windows 7 и Mac OS X 10.6 0,7).

Вам нужно создать новый объект, который наследует объект navigator и определить новый userAgent getter, чтобы скрыть исходный userAgent getter в navigator:

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

Ответ 3

Следующее решение работает в Chrome, Firefox, Safari, IE9 +, а также с 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
            });
        }
    }
}

Примеры:

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

Ответ 4

Использование Object.defineProperty должно добавить еще несколько браузеров в микс:

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

Этот код должен работать (и был протестирован) в Firefox 1.5 +, Chrome 6 +, Opera 10.5 + и IE9 +. К сожалению, Safari на любой платформе не позволяет изменять userAgent.

Изменить: Safari не позволяет изменять userAgent, но можно заменить весь объект навигатор, как указано в другом решении выше.

Ответ 5

Чтобы обновить этот поток, defineGetter больше не работает в Jasmine, поскольку он устарел. Однако я нашел, что это позволяет мне модифицировать геттер для navigator.userAgent в жасмине:

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

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

Просто помните, как сбросить объект навигатора, как только вы закончите тестирование в жасмине

Ответ 6

Полумесяц Свежий ответ правильный. Но есть проблема: __defineGetter__ устарел:

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

УстаревшиеЭта функция была удалена из веб-стандартов. Хотя некоторые браузеры все еще могут его поддерживать, он находится в процессе сбрасывается. Не используйте его в старых или новых проектах. Страницы или веб-приложения его использование может прерываться в любое время.

Вместо этого следует использовать defineProperty:

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

navigator.userAgent; // 'foo'

Ответ 7

Думаю, я бы взял подход к инъекции зависимостей. Вместо:

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'
    // ...
}

Эта конструкция до сих пор не полностью автоматизирована (вам нужно вручную переименовать геттер для выполнения вашего тестирования), и он добавляет кучу сложности в нечто такое же простое, как работа на navigator.userAgent, и я не уверен, как вы на самом деле идентифицировали бы ошибки в myFunction, но я просто подумал, что выброшу его там, чтобы дать вам некоторые идеи, как это можно решить.

Может быть, идея "инъекции зависимостей", представленная здесь, может каким-то образом быть интегрирована с FireUnit.

Ответ 8

Для тех, кто пытается сделать то же самое в TypeScript здесь, решение:

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

navigator.userAgent; // 'foo'

То же самое для языка:

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

Ответ 9

navigator.userAgent - свойство строки только для чтения, поэтому его невозможно отредактировать

Ответ 10

Выше ответы не работали для PhantomJS + TypeScript. Ниже код работал у меня:

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

Ответ 11

Нет, я сомневаюсь, что вы можете сделать это в javascript. Но с помощью Firefox User Agent Switcher вы можете протестировать любой пользовательский адрес, который вы хотите, поэтому почему бы просто не использовать это?

Ответ 12

Измените 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 webbrowser control, вы можете удвоить подмену как HTTP-запроса, так и JavaScript navigator.userAgent через 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