Javascript 使用Chrome扩展更改navigator.userAgent

Javascript 使用Chrome扩展更改navigator.userAgent,javascript,html,google-chrome,google-chrome-extension,Javascript,Html,Google Chrome,Google Chrome Extension,我正在尝试使用一个简单的chrome扩展来重载navigator.userAgent。由于内容脚本在独立的环境中运行,我尝试创建一个脚本元素并将逻辑写入其中。这发生在扩展的背景页面上 chrome.tabs.query({ active:!0 }, function(tabs) { var x = "window.navigator.__defineGetter__('userAgent', function() {" + "return 'Mozilla/5

我正在尝试使用一个简单的chrome扩展来重载navigator.userAgent。由于内容脚本在独立的环境中运行,我尝试创建一个脚本元素并将逻辑写入其中。这发生在扩展的背景页面上

chrome.tabs.query({
  active:!0
}, function(tabs) {
    var x = "window.navigator.__defineGetter__('userAgent', function() {" +
            "return 'Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Build/JOP40D)" +
            " AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile " + 
            "Safari/535.19'; });console.log(navigator.userAgent);";

    for (var i = 0;i < tabs.length;i++) {
      var code = 'var s = document.createElement("script"); s.text = "' + x +
                 '"; document.head.insertBefore(s, document.head.firstChild);' + 
                 'navigator.userAgent ="s"; console.log(navigator.userAgent);';

      // Inject into the tabs of choice - currently everything.
      chrome.tabs.executeScript(tabs[i].id, {
        code: code
      });
    }
  });
chrome.tabs.query({
活动:!0
},功能(选项卡){
var x=“window.navigator.\uuuuu defineGetter\uuuuu('userAgent',function(){”+
“返回'Mozilla/5.0(Linux;Android 4.2.1;en-us;Nexus 5 Build/JOP40D)”+
“AppleWebKit/535.19(KHTML,类似Gecko)Chrome/18.0.1025.166移动版”+
“Safari/535.19';});console.log(navigator.userAgent);”;
对于(变量i=0;i
脚本被附加到head元素,我可以看到UA字符串是通过在chrome控制台中尝试navigator.userAgent伪造的,因此我认为navigator对象被重载了

但这似乎不是一种有效的方式,或者根本没有发生,因为导航器对象没有更新,我通过发现了这一点——它仍然显示了用于Mac的UA


那么,我到底错过了什么

您是否正在尝试更改在请求中发送的用户代理标头?您必须使用declarativeWebRequest或WebRequestAPI


只有在发送请求后才会在页面中运行内容脚本。

navigator。userAgent
是只读属性。如果要更改
navigator.userAgent
,则需要创建一个新对象并复制属性,或者创建一个新对象并从
navigator
继承并分配一个新的getter/setter

我最近创建了这样一个扩展。我使用的是Linux,不过我偶尔会下载Chrome for Windows。以下扩展将用户代理更改为Chrome下载页面上的Windows XP:

contentscript.js
var-actualCode='('+函数(){
"严格使用",;
var navigator=window.navigator;
var修饰的导航器;
if(Navigator.prototype中的“userAgent”){
//Chrome 43+将所有属性从navigator移至原型,
//因此,我们必须修改原型而不是导航器。
modifiedNavigator=Navigator.prototype;
}否则{
//Chrome 42-在navigator上定义了属性。
modifiedNavigator=Object.create(导航器);
Object.defineProperty(窗口“导航器”{
值:modifiedNavigator,
可配置:false,
可枚举:false,
可写:false
});
}
//假装是Windows XP
对象。定义属性(修改的导航器{
用户代理:{
值:navigator.userAgent.replace(/\([^)]+\)/,'WindowsNT5.1'),
可配置:false,
可枚举:正确,
可写:false
},
应用程序版本:{
值:navigator.appVersion.replace(/\([^)]+\)/,'Windows NT 5.1'),
可配置:false,
可枚举:正确,
可写:false
},
站台:{
值:“Win32”,
可配置:false,
可枚举:正确,
可写:false
},
});
} + ')();';
var s=document.createElement('script');
s、 text内容=实际代码;
document.documentElement.appendChild;
s、 删除();
manifest.json
{
“名称”:“navigator.userAgent”,
“说明”:“将navigator.userAgent更改为Chrome下载页面上的Windows。”,
“版本”:“1”,
“清单版本”:2,
“内容脚本”:[{
“运行时间”:“文档开始时间”,
“js”:[“contentscript.js”],
“匹配项”:[
“*://www.google.com/intl/*/chrome/browser/*”
]
}]
}
如您所见,我不是动态插入它,而是确保我的代码在加载页面之前运行。此外,我正在使用其中一个技巧来更改页面的
navigator
,而不是独立内容脚本世界中的其他
navigator


注意,这只修改了从JavaScript中看到的userAgent。如果要修改发送到服务器的用户代理,请查看。

是的,我正在使用chrome.webRequest API修改标题中的UserAgent,但这仍然不足以更新navigator.UserAgent。所以,我试图在userAgent发送头请求时覆盖它。我在一周前想出了这个方法,忘了在这里更新。但您的解决方案与navigator的其他属性非常完美,这可能会帮助我实现完美的仿真。我还有一个问题,如果我在注入脚本之前使用chrome消息传递来确认后台页面中的内容,那么脚本的注入速度会稍微慢一些。在某些情况下,内联脚本会在消息传递完成之前执行。有解决办法吗?@SrikanthRayabhagi我在上列出了一些解决办法。这些都是黑客,你应该只把它们当作最后的手段。我在“UsAgent:{”中得到非法调用错误。行。知道这是怎么回事吗?我唯一做的更改是引用了整个内容,而不是让函数不带引号。@RyanAmos Chrome 43更改了内置对象的定义方式。我更新了答案,再试一次。有关在其他浏览器上也适用的代码,请参阅。