纯JS上传文档到CouchDB

Uploading documents to CouchDB in pure JS

我正在网络浏览器中编写游戏,我想制作一个高分列表。我希望它能保存高分,以便用户可以竞争,所以我在 Cloudant (CouchDB) 中创建了一个数据库,我计划将分数上传和下载到该数据库。

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]]}}");
}

失败并出现错误:
XMLHttpRequest 无法加载 http://reverse-snake.cloudant.com/highscores/highscores。预检响应无效(重定向)

我试过用 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]]}}"

它成功了。我错过了什么?

编辑:每个请求,失败的 http 请求的日志:http://pastebin.com/D97KwpM1

您的错误与 CORS 相关,curl 绕过了该检查(这是一个 "security" 功能,但检查是由浏览器完成的,因此安全性很弱)。

编辑 错误发生是因为 http => https 重定向。可以避免重定向,请参阅 ,但为什么浏览器会失败?

这是网络日志:

Request URL:http://reverse-snake.cloudant.com/highscores/highscores
Request Method:OPTIONS
Status Code:307 Internal Redirect
Response Headers
Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:null
Location:https://reverse-snake.cloudant.com/highscores/highscores
Non-Authoritative-Reason:HSTS

解释是在CORS机制中,在某些情况下,浏览器首先发送一个OPTIONS("preflight")请求从服务器获取一些能力信息。 PUT 请求有强制预检,而 GET 请求没有。无法重定向该 OPTIONS 请求。

答案非常简单。 CouchDB(和 Cloudant)需要安全的网络访问。网络日志揭示了这一点:

Get 请求发送到 http://... 并通过重定向回复;这导致 https://...

将请求转到 http://... 并通过重定向回复;这会导致失败。

唯一需要更改的是第 2 行,更改方法。不需要设置请求 headers。