0

When I use the fetch API (Or xmlhttprequest) I get a 0 byte response. Here is a sample of my code:

    fetch("https://myurl", {
      method: "POST",
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({content: content})
      }).then(function(res){  return res.text()}).then(function(res){ return cb(res);});

In the network tab, and in the console.log(res) in the callback, the response is empty. I should note that the response is including a CORS response specifying my chrome extension (which is making the request)

Access-Control-Allow-Origin: chrome-extension://asdjkljuewyrjkhighqwend

When I use the requests library (python) and make the same request (copying and pasting the body of the request) I get a valid json response.

resp = requests.post("https://myurl", json=data)
resp.json() ->> {content}

Additionally, when I inspect the server after the Fetch requests, I can see that it happily responded with the json to the request, but something on the browser seems to be blocking it from getting through.

Ben
  • 169
  • 1
  • 2
  • 8
  • res.text() is not a promise – Lawrence Cherone May 03 '19 at 22:48
  • 1
    Sadly it seems like it most certainly is - I changed it to }).then(function(res){ console.log(res.text()); return res.text()}).then(function(res){ return cb(res);}); and the output was Promise {} __proto__: Promise [[PromiseStatus]]: "resolved">[[PromiseValue]]: "" – Ben May 03 '19 at 22:53
  • 2
    See the answers at https://stackoverflow.com/a/55156266/441757 and https://stackoverflow.com/a/55175483/441757 and https://stackoverflow.com/a/55215898/441757. This is possibly the same problem (duplicate) as those. And see https://www.chromium.org/Home/chromium-security/extension-content-script-fetches – sideshowbarker May 04 '19 at 01:02

2 Answers2

3

You need to move all XHR requests to the background part of your extension. Chrome no longer accepts content scripts requests.

You can use runtime.sendMessage to send messages to a background process.

chrome.runtime.sendMessage(myMessageObject, async response => {
  // Here is the response returned by the background process
});

And here is how to receive messages from the background perspective.

chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {

  return true
})
DanteDiaze
  • 128
  • 1
  • 6
  • This definitely seems like the right direction to be going in, but when I switched to sending a message from my "popup.js" - chrome.runtime.sendMessage({from: 'popup', subject: 'DOMInfo'}, setDOMInfo); . I can see that it runs, but my listeners never get the message ( in background.js) chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { console.log("hit!"); }; << never triggers. I appreciate the help and its definitely getting in the right direction! – Ben May 06 '19 at 13:31
  • My manifest looks like "background": { "scripts": ["js/background.js"] }, "content_scripts": [ { "matches": [ "https://www.linkedin.com/recruiter/profile/*" ], "js": ["js/content.js", "js/popup.js", "js/browser_button_content.js"], "run_at": "document_end" } ], "browser_action": { "default_icon": "img/icon.png" }, "web_accessible_resources": ["popup.html"] } I'm wondering if the issue might be there? – Ben May 06 '19 at 13:32
  • 1
    This was definitely the root of the problem. Separately I found I had to use a combination of chrome.runtime.sendMessage to get messages to the background, and chrome.tabs.sendMessage to send messages to my content scripts. I was assuming I could use the same for both and that was what really nailed me. – Ben May 06 '19 at 20:45
-1

I believe you're indeed looking at a CORS issue. Try including the following headers in the response from your server:

Access-Control-Allow-Origin: * // you already hve this one Access-Control-Allow-Headers: Content-Type Access-Control-Allow-Methods: GET, PUT, POST, OPTIONS

Daniel
  • 571
  • 1
  • 5
  • 9