title: Injecting javascript variable before content script
body: <p>Using my background script background.js, I need to inject a dynamic variable as a content script before injecting another file inject.js also as a content script. Inject.js will need to have access to this variable and run it's code BEFORE any scripts on the page run. I am having difficulties accessing the dynamic variable from the inject.js content script.</p>
  
  <p>manifest.json</p>
  
  <pre><code>{
  "name": "Shape Shifter",
  "version": "1.0",
  "description": "Anti browser fingerprinting web extension. Generates randomised values for HTTP request headers, javascript property values and javascript method return types.",
  "manifest_version": 2,
  "icons": {
      "32": "icons/person-32.png",
      "48": "icons/person-48.png"
  },
  "background": {
      "persistent": true,
      "scripts": ["js/ua.js", "js/words.js", "js/lib/seedrandom.min.js", "js/random.js", "js/background.js"]
  },
  "browser_action": {
      "default_title": "Shape Shifter",
      "default_icon": "icons/person-32.png",
      "default_popup": "html/popup.html"
  },
  "content_scripts": [
    {
      "run_at": "document_end",
      "matches": ["&lt;all_urls&gt;"],
      "js": ["js/inject.js"] 
    }
  ],
  "permissions": [
      "webRequest",
      "webRequestBlocking",
      "webNavigation",
      "tabs",
      "activeTab",
      "storage",
      "&lt;all_urls&gt;"
  ],
  "web_accessible_resources": [
      "js/ua.js",
      "js/words.js",
      "js/lib/seedrandom.min.js",
      "js/random.js",
      "js/api/document.js",
      "js/api/navigator.js",
      "js/api/canvas.js",
      "js/api/history.js",
      "js/api/battery.js",
      "js/api/audio.js",
      "js/api/element.js"
  ]
  </code></pre>
  
  <p>}</p>
  
  <p>background.js</p>
  
  <pre><code>"use strict";
  
  console.log("Background Script Running ...");
  
  function getSeed(origin) {
      // Get a Storage object
      var storage = window.localStorage;
  
      // Do we already have a seed in storage for this origin or not?
      var seed = storage.getItem(origin);
  
      if (seed === null) {
          // Initialise a 32 byte buffer
          seed = new Uint8Array(32);
  
          // Fill it with cryptographically random values
          window.crypto.getRandomValues(seed);
  
          // Save it to storage
          storage.setItem(origin, seed);
      }
  
      return seed;
  }
  
  // Methods to get HTTP headers
  function getAcceptHeader(seed) {
      return "NotYetImplemented";
  }
  function getAcceptCharsetHeader(seed) {
      return "NotYetImplemented";
  }
  function getAcceptEncodingHeader(seed) {
      return "NotYetImplemented";
  }
  function getAcceptLanguageHeader() {
      // NOTE: TOR Browser uses American English
      return "en-US,en;q=0.5";
  }
  function getAuthorizationHeader(seed) {
      return "NotYetImplemented";
  }
  function getExpectHeader(seed) {
      return "NotYetImplemented";
  }
  function getFromHeader(seed) {
      return "NotYetImplemented";
  }
  function getHostHeader(seed) {
      return "NotYetImplemented";
  }
  function getIfMatchHeader(seed) {
      return "NotYetImplemented";
  }
  function getIfModifiedSinceHeader(seed) {
      return "NotYetImplemented";
  }
  function getIfNoneMatchHeader(seed) {
      return "NotYetImplemented";
  }
  function getIfRangeHeader(seed) {
      return "NotYetImplemented";
  }
  function getIfUnmodifiedSinceHeader(seed) {
      return "NotYetImplemented";
  }
  function getMaxForwardsHeader(seed) {
      return "NotYetImplemented";
  }
  function getProxyAuthorizationHeader(seed) {
      return "NotYetImplemented";
  }
  function getRangeHeader(seed) {
      return "NotYetImplemented";
  }
  function getRefererHeader() {
      // NOTE: From https://developer.mozilla.org/en-US/docs/Web/API/Document/referrer
      // NOTE: The value is an empty string if the user navigated to the page directly (not through a link, but, for example, via a bookmark).
      // NOTE: Since this property returns only a string, it does not give you DOM access to the referring page.
  
      // NOTE: Make websites think we always go to them directly rather than being referred.
      return "";
  }
  function getTEHeader(seed) {
      return "NotYetImplemented";
  }
  function getUserAgentHeader(seed) {
      Math.seedrandom(seed);
  
      return userAgents[randomNumber(0, userAgents.length)];
  }
  
  function rewriteHttpHeaders(e) {
      // Create URL object from url string
      var serverUrl = new URL(e.url);
  
      console.log(e);
  
      // Get the origin (hostname)
      var origin = serverUrl.hostname;
  
      var seed = getSeed(origin);
  
      console.log("Background - Seed for origin " + origin + ": " + seed);
  
      for (var header of e.requestHeaders) {
          if (header.name.toLowerCase() === "accept") {
          }
          else if (header.name.toLowerCase() === "accept-charset") {
          }
          else if (header.name.toLowerCase() === "accept-encoding") {
          }
          else if (header.name.toLowerCase() === "accept-language") {
              header.value = getAcceptLanguageHeader();
          }
          else if (header.name.toLowerCase() === "authorization") {
          }
          else if (header.name.toLowerCase() === "expect") {
          }
          else if (header.name.toLowerCase() === "from") {
          }
          else if (header.name.toLowerCase() === "host") {
          }
          else if (header.name.toLowerCase() === "if-match") {
          }
          else if (header.name.toLowerCase() === "if-modified-since") {
          }
          else if (header.name.toLowerCase() === "if-none-match") {
          }
          else if (header.name.toLowerCase() === "if-range") {
          }
          else if (header.name.toLowerCase() === "if-unmodified-since") {
          }
          else if (header.name.toLowerCase() === "max-forwards") {
          }
          else if (header.name.toLowerCase() === "proxy-authorization") {
          }
          else if (header.name.toLowerCase() === "range") {
          }
          else if (header.name.toLowerCase() === "referer") {
              header.value = getRefererHeader();
          }
          else if (header.name.toLowerCase() === "te") {
          }
          else if (header.name.toLowerCase() === "user-agent") {
              header.value = getUserAgentHeader(seed);
          }
      }
  
      return {requestHeaders: e.requestHeaders};
  }
  
  chrome.webRequest.onBeforeSendHeaders.addListener(rewriteHttpHeaders, {urls: ["&lt;all_urls&gt;"]}, ["blocking", "requestHeaders"]);
  
  chrome.webNavigation.onBeforeNavigate.addListener(function(details) {
      // Create URL object from url string
      var serverUrl = new URL(details.url);
  
      // Get the origin (hostname)
      var origin = serverUrl.hostname;
  
      var seed = "Some dynamic value";
  
      console.log("Injecting Value");
      chrome.tabs.executeScript(details.tabId, {code: "var seed = '" + seed + "';console.log(seed);", runAt: "document_start"}, function() {
          console.log("Value Injected");
      });
  });
  </code></pre>
  
  <p>inject.js</p>
  
  <pre><code>(function() {
    function inject(filePath) {
      var script = document.createElement('script');
      script.src = chrome.extension.getURL(filePath);
      script.onload = function() {
        this.remove();
      };
      (document.head || document.documentElement).appendChild(script);
    }
  
    function injectText(text) {
      var script = document.createElement('script');
      script.textContent = text;
      script.onload = function() {
        this.remove();
      };
      (document.head || document.documentElement).appendChild(script);
    }
  
    console.log("CONTENT SCRIPT RUNNING");
  
    console.log(seed); // SEED IS NOT DEFINED HERE ???
  
    injectText("var seed = 'hello';");
    console.log("[INFO] Injected Seed ...");
    inject("js/ua.js");
    console.log("[INFO] Injected UA ...");
    inject("js/words.js");
    console.log("[INFO] Injected Words ...");
    inject("js/lib/seedrandom.min.js");
    console.log("[INFO] Injected Seed Random ...");
    inject("js/random.js");
    console.log("[INFO] Injected Random ...");
    inject("js/api/document.js");
    console.log("[INFO] Injected Document API ...");
    inject("js/api/navigator.js");
    console.log("[INFO] Injected Navigator API ...");
    inject("js/api/canvas.js");
    console.log("[INFO] Injected Canvas API ...");
    inject("js/api/history.js");
    console.log("[INFO] Injected History API ...");
    inject("js/api/battery.js");
    console.log("[INFO] Injected Battery API ...");
    inject("js/api/audio.js");
    console.log("[INFO] Injected Audio API ...");
    inject("js/api/element.js");
    console.log("[INFO] Injected Element API ...");
  })();
  </code></pre>
  
  <p>I get the error when trying to log the seed to the console:</p>
  
  <pre><code>inject.js:26 Uncaught ReferenceError: seed is not defined
      at inject.js:26
      at inject.js:52
  </code></pre>
  
  <p>Any ideas?</p>