Griffin Young
Griffin Young

Reputation: 243

high-order function causes unsafe eval in chrome extension

I am making a very simple chrome extension to randomly change the wallpaper on my chromebook. But I am getting a strange error in the Javascript console after I load it:

Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' blob: filesystem: chrome-extension-resource:". @ background.js:27

Here is my manifest.json:

{
  "manifest_version": 2,

  "name": "Abyss Wallpapers for Chrome OS",
  "description": "Sets the Chrome OS wallpaper to a random wallpaper from the
                      Wallpaper Abyss (wall.alphacoders.com), once a minute",
  "version": "1.0",
  "background":
  {
    "scripts":["background.js"]
  },
  "permissions": [
    "wallpaper",
    "https://wall.alphacoders.com/api2.0/",
    "background"
  ]
}

And here is my background.js:

var baseUrl = "https://wall.alphacoders.com/api2.0/get.php?"
var apiKey = "c160c64ef4c79e61e325ddf944183dfe"
var params = "auth=" + apiKey + "&method=random"
var interval = 30000;
var xhr = new XMLHttpRequest();
xhr.open("GET", baseUrl + params, true);
xhr.onreadystatechange = function()
{
  if (xhr.readyState == 4 && xhr.status == 200)
  {
    var data = xhr.responseText;
    if (data.success)
    {
      chrome.wallpaper.setWallpaper
      (
        {url:data.wallpapers[1].url_image,
        layout:"CENTER_CROPPED",
        filename:data.wallpapers[1].id + "." + data.wallpapers[1].file_type},
        function(thumbnail)
        {
          thumbnail = null;
        }
      )
    }
  }
}
setInterval(xhr.send(), interval);

It appears that it is rejecting the setInterval() method, but there is no eval or even a string there.

EDIT: So I changed the setInterval() statement to reflect Bergi's answer, and now the background script runs for about a minute, meaning that the interval was set, but I get another error after that:

Uncaught InvalidStateError: Failed to execute 'send' on 'XMLHttpRequest': The object's state must be OPENED.(anonymous function) @ background.js:27

Why would the object not be open when I specifically called xhr.open() in line 5?

Upvotes: 1

Views: 1437

Answers (2)

Xan
Xan

Reputation: 77531

You can only .send() once after you create and .open() an XHR.

If you need to do this on interval, you need to re-create XHR each time.

Upvotes: 0

Bergi
Bergi

Reputation: 664620

setInterval, when being passed a non-function value, takes the first argument for a code string and evals it. You are passing the return value of xhr.send(), which is indeed not a function.

Solve this by using

setInterval(function() { xhr.send(); }, interval);

or

setInterval(xhr.send.bind(xhr), interval);

which I guess is also what you actually intended to do.

Upvotes: 5

Related Questions