Издеваясь над useragent в javascript?
Я ищу способ программно изменить навигатора.userAgent на лету. В моей неудачной попытке получить автоматический модульный тестер javascript я сдался и попытался начать использовать fireunit. Сразу же я врезался в одну из стен использования фактического браузера для тестирования javascript.
в частности, мне нужно менять навигатор.userAgent для имитации нескольких сотен строк userAgent для обеспечения правильного обнаружения и покрытия данной функции. навигатор.userAgent только для чтения, так что я, кажется, застрял! Как я могу издеваться над навигатором.userAgent? User Agent Switcher (плагин) может переключать useragent FF, но могу ли я сделать это в javascript?
13 ответов:
попробуй:
navigator.__defineGetter__('userAgent', function(){ return 'foo' // customized user agent }); navigator.userAgent; // 'foo'пробовал в FF2 и FF3.
на решение Crescent Fresh, переиначивая
navigator.userAgentgetter, похоже, не работает в Safari 5.0.5 (на Windows 7 и Mac OS X 10.6.7).нужно создать новый объект, который наследует от
navigator"объект" и определить новыйuserAgentgetter, чтобы скрыть оригиналuserAgentgetter innavigator:var __originalNavigator = navigator; navigator = new Object(); navigator.__proto__ = __originalNavigator; navigator.__defineGetter__('userAgent', function () { return 'Custom'; });
следующее решение работает в 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');
Использование Объекта.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.
Edit: Safari не позволяет изменить userAgent, но можно заменить весь навигатор объект, как указано в другом решение выше.
Crescent Fresh ответ правильный. Но есть проблема:
__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'
чтобы обновить этот поток, defineGetter больше не работает в Jasmine, поскольку он был устаревшим. Однако я обнаружил, что это позволяет мне изменить геттер для навигатора.userAgent в жасмин:
navigator = { get userAgent() { return 'agent'; } } console.log(navigator.userAgent); // returns 'agent'просто помните, сброс объекта навигатора, как только вы закончите тестирование в jasmine
для тех, кто пытается сделать то же самое в TypeScript вот решение:
(<any>navigator)['__defineGetter__']('userAgent', function(){ return 'foo'; }); navigator.userAgent; // 'foo'или то же самое для языка:
(<any>navigator)['__defineGetter__']('language', function(){ return 'de-DE'; });
Я думаю, что я бы взял подход инъекции зависимости. Вместо:
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.
navigator.userAgentявляется строковым свойством только для чтения, поэтому его невозможно редактировать
выше ответы не работали для PhantomJS + TypeScript. Ниже код работал для меня:
var __originalNavigator = navigator; (window as any).navigator = new Object(); navigator["__proto__"] = __originalNavigator["__proto__"]; navigator["__defineGetter__"]('userAgent', function () { return 'Custom'; });
поздно к этой теме, но для Karma + Jasmin и Typescript и хотите установить свойство userAgent это сделает это:
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 });эта статья помогла:https://www.codeproject.com/Tips/1036762/Mocking-userAgent-with-JavaScript
Нет, я сомневаюсь, что вы можете сделать это в JavaScript. Но с помощью переключателя агента пользователя Firefox вы можете проверить любой useragent, который вы хотите, так почему бы просто не использовать его?
сменить навигатор.userAgent на Firefox и Opera через defineGetter
navigator.__defineGetter__('userAgent', function(){ return( "iPhone 5" ); }); alert( navigator.userAgent ); //iPhone 5сменить навигатор.userAgent на IE и Opera через экземпляр объекта
var navigator = new Object; navigator.userAgent = 'iPhone 5'; alert( navigator.userAgent ); //iPhone5хорошо, что если вы работаете над управлением IE webbrowser, вы можете дважды подделать как HTTP-запрос, так и JavaScript-навигатор.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
Comments