Search code examples
javascriptcouchdbcloudant

Uploading documents to CouchDB in pure JS


I'm writing a game in a web browser, and I'd like to make a highscores list. I'd like it to save highscores so users can compete, so I've created a database in Cloudant (CouchDB) to which I plan to upload & download the scores.

function uploadHighscores() {
  var req = new XMLHttpRequest();
  req.open('PUT', 'http://reverse-snake.cloudant.com/highscores/highscores', true); // METHOD, url, async
  req.onload = function() { // Asynchronous callback.
    console.log(req.responseText);
    console.log("Scores uploaded");
  }
  req.setRequestHeader('Content-Type', 'application/json');
  console.log("Sending scores...");

  req.send("{\"_id\": \"highscores\", \"_rev\": \"6-f29fd233a21c65e3f4a7485f36c46ae4\", \"data\":{\"scores\":[999, 999, 999, 999, 999], \"times\":[[59, 59, 999], [59, 59, 999], [59, 59, 999], [59, 59, 999], [59, 59, 999]]}}");
}

This fails with the error:
XMLHttpRequest cannot load http://reverse-snake.cloudant.com/highscores/highscores. Response for preflight is invalid (redirect)

I've tried doing this request with curl:

curl http://reverse-snake.cloudant.com/highscores/highscores -X PUT -d "{\"_id\": \"highscores\", \"_rev\": \"6-f29fd233a21c65e3f4a7485f36c46ae4\", \"data\":{\"scores\":[999, 999, 999, 999, 999], \"times\":[[59, 59, 999], [59, 59, 999], [59, 59, 999], [59, 59, 999], [59, 59, 999]]}}"

and it succeeds. What am I missing?

Edit: Per request, the log of the failed http request: http://pastebin.com/D97KwpM1


Solution

  • The answer is painfully simple. CouchDB (and Cloudant) require secure network access. This was revealed by the network logs:

    Get requests went to http://... and were replied with a redirect; this lead to https://...

    Put requests went to http://... and were replied with a redirect; this lead to a failure.

    The only change that needs to be made is on line 2, changing the method. Setting request headers is not required.