How to communicate between popup.js and background.js in chrome extension?

Solution 1:

Method - A :
Using Long Lived Connections you can communicate from background.js to popup.js of extension page for any activities( Here i have included popup.html and only initiated sample communication from popup.js as a sample)

background.js

 chrome.extension.onConnect.addListener(function(port) {
      console.log("Connected .....");
      port.onMessage.addListener(function(msg) {
           console.log("message recieved" + msg);
           port.postMessage("Hi Popup.js");
      });
 })

popup.js

 var port = chrome.extension.connect({
      name: "Sample Communication"
 });
 port.postMessage("Hi BackGround");
 port.onMessage.addListener(function(msg) {
      console.log("message recieved" + msg);
 });

Method - B :
Direct Manipulation of DOM* if your end result is modification of DOM, you can achieve with this

popup.html

<html>
    <head>
        <script src="popup.js"></script>
    </head>
    <body>
        <div id="x" value="m">Some thing</div>
    </body>
</html>

background.js

var views = chrome.extension.getViews({
    type: "popup"
});
for (var i = 0; i < views.length; i++) {
    views[i].document.getElementById('x').innerHTML = "My Custom Value";
}

Method - C :

Using Long Lived Connections you can communicate from background.js to popup.js of extension page for any activities( Here i have not included popup.html and initiated sample communication from background.js;

background.js

chrome.browserAction.onClicked.addListener(function(tab) {

    var port = chrome.extension.connect({
        name: "Sample Communication"
    });
    port.postMessage("Hi BackGround");
    port.onMessage.addListener(function(msg) {
        console.log("message recieved" + msg);
    });

});

I have changed your code and made it running after eliminating some stuff and making it a simple version. Add your code for AJAX requests and HTML DOM on this skeleton( Make sure you add <script> tag in head section and put chrome.extension.onConnect.addListener out of (xhr.readyState == 4) code;)

popup.html

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

manifest.json

{
    "name": "Demo",
    "version": "1.0",
    "manifest_version": 2,
    "description": "This is a demo",
    "browser_action": {
        "default_popup": "popup.html"
    },
    "background": {
        "scripts": ["background.js"]
    },
    "permissions": ["<all_urls>",
        "storage",
        "tabs"
    ]
}

background.js

chrome.extension.onConnect.addListener(function(port) {
    console.log("Connected .....");
    port.onMessage.addListener(function(msg) {
        console.log("message recieved " + msg);
        port.postMessage("Hi Popup.js");
    });
});

popup.js

var port = chrome.extension.connect({
    name: "Sample Communication"
});
port.postMessage("Hi BackGround");
port.onMessage.addListener(function(msg) {
    console.log("message recieved" + msg);
});

Solution 2:

This can be used in 2 way communication. Same code goes in both the files.

popup.js & background.js

//for sending a message
chrome.runtime.sendMessage({greeting: "hello"}, function(response) {

});

//for listening any message which comes from runtime
chrome.runtime.onMessage.addListener(messageReceived);

function messageReceived(msg) {
   // Do your work here
}

Ref: https://developer.chrome.com/extensions/runtime#method-sendMessage