【问题标题】:Custom Navigator overwritten after document load文档加载后覆盖自定义导航器
【发布时间】:2016-11-05 00:26:06
【问题描述】:

我正在编写一个简单的 Chrome 扩展程序,试图欺骗您当前的用户代理。我刚刚发现了this question 并在我的代码中实现了它。

以下是尝试替换当前用户代理字符串的内容脚本,设置为在document_start 运行:

let useragent, actualCode, timer = null;
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.useragent) {
    sendResponse({error: false});
    useragent = request.useragent;
  }
  else sendResponse({error: true});
});

var receivedUA = function() {
  if (useragent != null) {
    window.clearInterval(timer);
    actualCode = function(userAgent) {
      console.log('im being called');
      'use strict';
      let navigator = window.navigator;
      let modifiedNavigator;

      if ('userAgent' in Navigator.prototype) {
        modifiedNavigator = Navigator.prototype;
      } else {
        modifiedNavigator = Object.create(navigator);
        Object.defineProperty(window, 'navigator', {
          value: modifiedNavigator,
          configurable: false,
          enumerable: false,
          writable: false
        });
        Object.defineProperty(navigator, 'navigator', {
          value: modifiedNavigator,
          configurable: false,
          enumerable: false,
          writable: false
        });
      }

      Object.defineProperties(modifiedNavigator, {
        userAgent: {
          value: userAgent.useragent,
          configurable: false,
          enumerable: true,
          writable: false
        },
        appVersion: {
          value: userAgent.appversion,
          configurable: false,
          enumerable: true,
          writable: false
        },
        platform: {
          value: userAgent.platform,
          configurable: false,
          enumerable: true,
          writable: false
        }
      });

      console.dir(modifiedNavigator);

    };
    let evt = new Event('reset');
    document.documentElement.addEventListener('reset', actualCode(useragent));
    document.documentElement.dispatchEvent(evt);
    document.documentElement.removeEventListener('reset', actualCode(useragent));
  }
  else {
    window.clearTimeout(timer);
    timer = window.setTimeout(receivedUA, 100);
  }
}
receivedUA();

但是,我在 whatsmyua.com 上进行测试,并且在文档开始加载时调用代码,但在加载之后,它会显示我真正的用户代理,并且在控制台上键入 window.navigator.userAgent 会返回相同的结果。我在这里错过了什么?

【问题讨论】:

    标签: javascript google-chrome-extension


    【解决方案1】:

    也许您应该使用chrome.webRequest API here 来避免这种复杂性。这是一个稍微修改的示例,它将从上面的链接输出 User-Agent 标头的对象:

    chrome.webRequest.onBeforeSendHeaders.addListener(
        function(details) {
            for (var i = 0; i < details.requestHeaders.length; ++i) {
                if (details.requestHeaders[i].name === 'User-Agent') {
                  console.log(details.requestHeaders[i]);
                  break;
                }
              }
              return {requestHeaders: details.requestHeaders};
        },
        {urls: ["<all_urls>"]},
        ["blocking", "requestHeaders"]
    );
    

    另外..你应该把它添加到你的后台脚本中(见here

    【讨论】:

    • 我认为回答问题的一部分是解释为什么它不起作用,特别是因为您的建议不会影响window.navigator
    • 我已经在我的代码中使用了这部分。我认为绝大多数网站都依赖window.navigator 来检索用户代理而不是 HTTP 标头。
    • 那么,有什么办法可以防止它被覆盖吗?
    【解决方案2】:

    如果您检查http://www.whatsmyua.com/ 的源代码,您可以看到它在页面加载时获取用户代理,并在正文开头的内联脚本中加载:

    function getUa() { return decodeURIComponent(location.hash.replace('#', '')) || navigator.userAgent; }

    所以这里的答案是时机:谁会更快 - 你的内容脚本或页面脚本。 该页面正在获胜。它在内容脚本覆盖它之前检索用户代理。

    您可以将页面下载为 html,在 localhost 上运行,并在其中放置带有时间戳的额外日志记录以测量时间。

    还要确保您使用 "run_at": "document_start" 作为上下文脚本。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-12
      • 2023-01-19
      • 1970-01-01
      • 2012-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      相关资源
      最近更新 更多