문제

저는 navigator.userAgent를 프로그래밍 방식으로 즉석에서 변경하는 방법을 찾고 있습니다.자동화된 자바스크립트 단위 테스터를 얻으려는 시도가 실패하자 포기하고 FireUnit을 사용하려고 시도했습니다.즉시, 나는 자바스크립트 테스트를 위해 실제 브라우저를 사용하는 벽 중 하나에 부딪혔습니다.

특히 특정 기능에 대한 적절한 감지 및 적용 범위를 보장하기 위해 수백 개의 userAgent 문자열을 시뮬레이션하도록 navigator.userAgent를 변경해야 합니다.navigator.userAgent는 읽기 전용이므로 멈춘 것 같습니다!navigator.userAgent를 어떻게 모의할 수 있나요?User Agent Switcher(플러그인)는 FF의 useragent를 전환할 수 있는데 javascript 내에서 할 수 있나요?

도움이 되었습니까?

해결책

노력하다:

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

navigator.userAgent; // 'foo'

FF2와 FF3에서 시도했습니다.

다른 팁

추가 Crescent Fresh의 솔루션, 재정의 navigator.userAgent Getter는 Safari 5.0.5에서 작동하지 않는 것 같습니다 (Windows 7 & Mac OS x 10.6.7).

상속하는 새 개체를 만들어야합니다. navigator 새로운 것을 반대하고 정의합니다 userAgent 원본을 숨기려고합니다 userAgent getter in navigator:

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

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+, 크롬 6+, 오페라 10.5+ 그리고 IE9+. 불행히도 모든 플랫폼의 Safari는 UserAgent를 변경할 수 없습니다.

편집 : Safari는 사용자 에이전트를 변경할 수 없지만 전체를 대체 할 수 있습니다. 항해자 위의 다른 솔루션에서 지적한 대상.

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에서 작동하지 않습니다. 그러나 나는 이것이 Jasmine의 Navigator.useragent의 getter를 수정할 수 있음을 발견했습니다.

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

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

자스민에서 테스트를 마치면 네비게이터 개체를 재설정하는 것을 기억하십시오.

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

이 디자인은 아직 완전히 자동화되지 않았으며(테스트를 수행하려면 getter의 이름을 수동으로 변경해야 함) 작업처럼 간단한 것에 많은 복잡성을 추가합니다. navigator.userAgent, 실제로 버그를 어떻게 식별할지 잘 모르겠습니다. myFunction, 하지만 저는 이 문제를 어떻게 처리할 수 있는지 몇 가지 아이디어를 제공하기 위해 그것을 거기에 던져야겠다고 생각했습니다.

어쩌면 여기에 제시된 "의존성 주입" 아이디어가 어떻게든 FireUnit과 통합될 수 있을 것입니다.

단위 테스트에서 사용자 가건 값을 변경해야하므로 Tyler Long의 솔루션은 작동하지만 초기 사용자 가건을 복원하거나 두 번 이상 변경하려면 속성을 구성 가능한 것으로 설정해야 할 것입니다.

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

그렇지 않으면 당신은 a TypeError: Cannot redefine property 오류. Chrome Headless에서 나를 위해 일합니다.

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 and 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

DefineGetter를 통해 Firefox 및 Opera에서 Navigator.useragent를 변경하십시오

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

alert( navigator.userAgent ); //iPhone 5

객체 인스턴스를 통해 IE 및 Opera에서 Navigator.useragent를 변경하십시오

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

alert( navigator.userAgent ); //iPhone5

좋은 점은 IE Webbrowser Control에서 작업하면 execscript를 통해 HTTP 요청과 JavaScript Navigator.useragent를 두 배로 스푸핑 할 수 있다는 것입니다.

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

아니요, JavaScript 내에서 할 수 있다고 의심 스럽습니다. 그러나 Firefox의 사용자 에이전트 스위처를 사용하면 원하는 사용자 에이전트를 테스트 할 수 있으므로 왜 사용하지 않겠습니까?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top