Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get input field value from Chrome Extension

I am working to learn how to build a Google Chrome Extension. I have a contact form on a webpage that I'm using for testing. I'm trying to create an extension that will read the input field values from that form. At this time, I have:

manifest.json

{
    "manifest_version": 2,

    "name": "Contact Form Friend",
    "description": "This extension gets contact form info.",
    "version": "1.0",

    "browser_action": {
      "default_icon": "icon.png",
      "default_popup": "popup.html"
    },

    "permissions": [
      "activeTab",
      "<all_urls>"
    ]
  }

popup.html

<!doctype html>
<html>
  <head>
    <title>Getting Started Extension's Popup</title>
    <style type="text/css">
      body {
        margin: 10px;
        white-space: nowrap;
      }

      h1 {
        font-size: 15px;
      }

      #container {
        align-items: center;
        display: flex;
        justify-content: space-between;
      }
    </style>

    <script src="popup.js"></script>
  </head>

    <body>
        <h1>Info</h1>
        <div id="info">

        </div>
    </body>
</html>

popup.js

function getHost() {
    return document.documentElement;
}

document.addEventListener('DOMContentLoaded', () => {
    const infoDisplay = document.getElementById('info');    
    const scriptToRun = `(${getHost})()`;

    // Run the script in the context of the tab
    chrome.tabs.executeScript({
      code: scriptToRun 
    }, (result) => {            
      var values = [];

      var inputFields = result.getElementsByTagName('input');
      infoDisplay.innerHTML = 'inputs: ' + inputFields.length;
      for (var i = 0; i < inputFields.length; i++) {
        values.push(inputFields[i].value);
      }

      infoDisplay.innerHTML += '<br />fields: ' + values.length;
    });
});

When I run this, it acts like it can't access the input fields from the web page the user is on (not the extension's web page). What am I doing wrong? Am I missing a permission? I don't believe so. However, it's not working and I'm not sure why.

Thank you for your help.

like image 731
Some User Avatar asked Jan 30 '18 16:01

Some User


People also ask

How do I enable tools in Chrome?

From the Chrome menu: Open the Chrome menu and go to “More Tools” > “Developer Tools.” Finally, you can right-click (Windows) or Ctrl-click (Mac) anything on a web page and select “Inspect Element” to open Developer Tools.

What are Chrome extensions?

Google Chrome extensions are programs that can be installed into Chrome in order to change the browser's functionality. This includes adding new features to Chrome or modifying the existing behavior of the program itself to make it more convenient for the user.


1 Answers

As reported by Gabriel Bleu you need a content script to interact with web pages inside Chrome tabs.

Here below is an example of Chrome Extension where a content script exposes two "commands" to popup.js.

See code comments for explanation.

manifest.json (similar to yours)

{
  "name": "My ext",
  "version": "0.1",
  "description": "my desc",
  "permissions": [
    "activeTab",
    "<all_urls>"
  ],
  "icons": {
    "128": "icon-128.png"
  },
  "browser_action": {
      "default_title": "My ext",
      "default_icon": "icon.png",
      "default_popup": "popup.html"
  },
  "manifest_version": 2,
  "content_security_policy": "script-src 'self' https://ajax.googleapis.com object-src 'self'"
}

popup.html (similar to yours except for jQuery usage for easy DOM manipulation)

<html>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script type="application/javascript" charset="utf-8" src="popup.js"></script>
</head>
<body class="body-popup">
    <button id="btn_check" class="btn btn-warning">check current tab</button>
    <hr>
    <div id="pg_url"></div>
    <hr>
    <div id="log"></div>
</body>
</html>

popup.js

$(function() {
    $('#btn_check').click(function() { checkCurrentTab(); });
});

function checkCurrentTab() {
    chrome.tabs.query({'active': true, 'lastFocusedWindow': true}, function (tabs) {
        var url = tabs[0].url;
        console.log("checkCurrentTab: "+url);
        $(".pg_url").text(url);

        // request content_script to retrieve title element innerHTML from current tab
        chrome.tabs.sendMessage(tabs[0].id, "getHeadTitle", null, function(obj) {
            console.log("getHeadTitle.from content_script:", obj);
            log("from content_script:"+obj);
        });

    });
}

document.addEventListener('DOMContentLoaded', function () {
    chrome.windows.getCurrent(function (currentWindow) {
        chrome.tabs.query({active: true, windowId: currentWindow.id}, function(activeTabs) {
            // inject content_script to current tab
            chrome.tabs.executeScript(activeTabs[0].id, {file: 'content_script.js', allFrames: false});
        });
    });
});

function log(txt) {
    var h = $("#log").html();
    $("#log").html(h+"<br>"+txt);
}

content_script.js

// you will see this log in console log of current tab in Chrome when the script is injected
console.log("content_script.js");

chrome.runtime.onMessage.addListener(function(cmd, sender, sendResponse) {
    console.log("chrome.runtime.onMessage: "+cmd);
    switch(cmd) {
    case "getHtml":
        // retrieve document HTML and send to popup.js
        sendResponse({title: document.title, url: window.location.href, html: document.documentElement.innerHTML});
        break;
    case "getHeadTitle":
        // retrieve title HTML and send to popup.js
        sendResponse(document.getElementsByTagName("title")[0].innerHTML);
        break;      
    default:
        sendResponse(null);
    }
});

P.S.: obviously jQuery is not mandatory

like image 101
beaver Avatar answered Sep 19 '22 20:09

beaver