javascript - 使用 Chrome 扩展更改 navigator.userAgent

标签 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.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
      });
    }
  });

脚本被附加到 head 元素,我可以看到 UA 字符串是通过在 chrome 的控制台中尝试 navigator.userAgent 欺骗的字符串,所以我相信导航器对象已过载。

但这似乎不是有效的方法或根本没有发生,因为导航器对象没有更新,我通过 - http://www.quirksmode.org/js/detect.html 发现了这一点。仍然显示 Mac 的 UA。

那么,我到底错过了什么?

最佳答案

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

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

内容脚本.js

var actualCode =  '(' + function() {
    'use strict';
    var navigator = window.navigator;
    var modifiedNavigator;
    if ('userAgent' in Navigator.prototype) {
        // Chrome 43+ moved all properties from navigator to the prototype,
        // so we have to modify the prototype instead of navigator.
        modifiedNavigator = Navigator.prototype;

    } else {
        // Chrome 42- defined the property on navigator.
        modifiedNavigator = Object.create(navigator);
        Object.defineProperty(window, 'navigator', {
            value: modifiedNavigator,
            configurable: false,
            enumerable: false,
            writable: false
        });
    }
    // Pretend to be Windows XP
    Object.defineProperties(modifiedNavigator, {
        userAgent: {
            value: navigator.userAgent.replace(/\([^)]+\)/, 'Windows NT 5.1'),
            configurable: false,
            enumerable: true,
            writable: false
        },
        appVersion: {
            value: navigator.appVersion.replace(/\([^)]+\)/, 'Windows NT 5.1'),
            configurable: false,
            enumerable: true,
            writable: false
        },
        platform: {
            value: 'Win32',
            configurable: false,
            enumerable: true,
            writable: false
        },
    });
} + ')();';

var s = document.createElement('script');
s.textContent = actualCode;
document.documentElement.appendChild(s);
s.remove();

list .json

{
    "name": "navigator.userAgent",
    "description": "Change navigator.userAgent to Windows on Chrome's download page.",
    "version": "1",
    "manifest_version": 2,
    "content_scripts": [{
        "run_at": "document_start",
        "js": ["contentscript.js"],
        "matches": [
            "*://www.google.com/intl/*/chrome/browser/*"
        ]
    }]
}

如你所见,我是 declaring the content script而不是动态插入它,以确保我的代码在页面加载之前运行。此外,我正在使用其中一种技巧 described in this answer更改页面的 navigator 而不是隔离内容脚本世界中的其他一些 navigator

请注意,这只会修改从 JavaScript 中看到的 userAgent。如果您想修改发送到服务器的用户代理,请查看 Associate a custom user agent to a specific Google Chrome page/tab .

关于javascript - 使用 Chrome 扩展更改 navigator.userAgent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23202136/

相关文章:

html - fb like 按钮在所有 ie 版本的页面加载上创建白色背景

c# - 为什么 Response.Redirect() 在 Chrome 中有效,但在 IE 中无效?

javascript - 将本地存储中保存的数据显示到 html 页面上

html - 响应式布局不在 FireFox 中调整大小

javascript - grunt 未定义 - AngularJs

html - pdfkit 生成小比例的 pdf

google-chrome - ipython 笔记本内核运行,但没有连接

javascript - 无法在 Chrome 扩展内发送 jQuery Ajax HTTP 请求

javascript - 我的 Canvas 动画的静音按钮

javascript - 无法通过单选类型检查计算 js 中的总数