Javascript 用纯JS将文档上传到CouchDB

Javascript 用纯JS将文档上传到CouchDB,javascript,couchdb,cloudant,Javascript,Couchdb,Cloudant,我正在网络浏览器中编写一个游戏,我想列出一个高分列表。我希望它能保存高分,这样用户就可以竞争了,所以我在Cloudant(CouchDB)中创建了一个数据库,我计划上传和下载分数 function uploadHighscores() { var req = new XMLHttpRequest(); req.open('PUT', 'http://reverse-snake.cloudant.com/highscores/highscores', true); // METHOD, u

我正在网络浏览器中编写一个游戏,我想列出一个高分列表。我希望它能保存高分,这样用户就可以竞争了,所以我在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。飞行前的响应无效(重定向)

我已尝试使用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请求的日志:

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

编辑由于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机器中,在某些情况下,浏览器首先发送一个选项(“飞行前”)请求,以从服务器获取一些能力信息。PUT请求具有强制预飞行,GET请求没有。该选项请求无法重定向。

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

将请求转到http://... 并得到了重新定向的回复;这导致https://...

将请求发送到http://... 并得到了重新定向的回复;这导致了失败


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

我知道CORS正在工作,因为A.我在Cloudant和B上启用了它。我可以在浏览器中成功获取请求。CouchDB使用_rev属性处理文档冲突。如果发送的PUT(或POST)请求没有此属性,CouchDB将不允许上载文档。“我可以在浏览器中成功获取请求”=>到您的DB?你做得怎么样?请求打开('GET','',true);“如果发送的PUT(或POST)请求没有此属性,CouchDB将不允许上载文档”=>这将非常不方便,您是否尝试了不带
\u rev
的插入?当您说“更改方法”时,是指https而不是http?如果删除
setRequestHeader
,您也会删除预飞,因此这也应该允许重定向,对吗?将协议更改为https可以在使用或不使用setRequestHeader的情况下工作。是的,https可以工作,但不清楚的是问题的第二部分“为什么http在PUT时重定向使用curl”。我的理解是,删除
setRequestHeader
应该删除导致重定向失败的CORS预飞行。事实并非如此,所以我猜所有的PUT请求都是由浏览器预引导的。