CouchDB中的_users数据库不允许使用HTTP OPTIONS方法

时间:2015-08-31 06:17:29

标签: cors couchdb preflight

我正在尝试从连接到另一个域的CouchDB的应用程序中更改用户的密码。我的代码或多或少与CouchDB Docs中的示例相同,即获取文档,更改数据,然后发送带有更改的PUT请求。 PUT请求发生问题 - 由于CORS,浏览器在发送PUT请求之前尝试执行OPTIONS请求,但OPTIONS请求返回405 Method Not Allowed。

有没有人知道如何解决这个问题?

以下是请求标题,以防它有用:

OPTIONS /_users/org.couchdb.user:clinic_admin HTTP/1.1
Host: localhost:15984
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: PUT
Origin: https://localhost:15000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36
Access-Control-Request-Headers: content-type, if-match
Accept: */*
Referer: https://localhost:15000/webapp/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,ja;q=0.6,sv;q=0.4,zh-CN;q=0.2

2 个答案:

答案 0 :(得分:8)

这里有两种选择。我更喜欢选项#2,但我会从#1开始。

选项1:正确配置CORS

CouchDB中的405错误通常是由于配置错误造成的,例如:不包括所有可能的标题和方法,如果你想支持所有的浏览器/设备,它们有很多。

在PouchDB团队中,我们将“最佳实践”收集到一个单独的模块中:add-cors-to-couchdb,它应该适用于CouchDB 1.6.1和CouchDB 2.0。跑吧:

npm install --global add-cors-to-couchdb
add-cors-to-couchdb http://example.com:5984 -u admin_username -p admin_password

这应该可以解决你的问题;如果没有,请查看成功使用此方法的PouchDBpouchdb-authentication的测试,以针对在localhost:5984运行的数据库进行测试(包括更改用户的密码,这就是您所需要的试图这样做。)

选项2:避免使用反向代理的CORS

这是最好的选择。最好有几个原因:

  1. 花几分钟配置Apache / nginx以完全避免使用CORS,以后为了让CORS正常工作而省去头痛
  2. CORS的性能低于无CORS,因为浏览器需要执行预检OPTIONS请求,这会增加额外的延迟,尤其是在复制期间
  3. 移动混合应用程序也更容易; Cordova已a one-liner option将某些域列入白名单并避免使用CORS。
  4. 我通常使用CouchDB的Nginx as a reverse proxy指南并路由到example.com/couchdb运行的数据库。 E.g:

    location /couchdb {
        rewrite /couchdb/(.*) /$1 break;
        proxy_pass http://localhost:5984;
        proxy_redirect off;
        proxy_buffering off;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    

    请注意,这可能会破坏/_utils(Futon / Fauxton),但在这种情况下最好的办法是通过SSH建立到服务器的反向隧道并在本地查看:

    ssh -L3000:localhost:5984 user@example.com
    # now open localhost:3000/_utils in a browser
    

    你可能不希望Futon / Fauxton无论如何都要向世界展示。

    这里的优点是你可以使用Nginx / Apache来阻止某些方法或CouchDB的某些部分,这通常比CouchDB中的HTTP选项更灵活。

答案 1 :(得分:2)

我没有直接连接到CouchdB实例,而是使用Apache作为代理,这样可以提高灵活性。 CouchDB有时完全禁止OPTIONS请求(例如_bulk_docs仅允许POST,这导致405个错误,完全阻止复制)。为了在执行CORS请求时解决这个问题,我将以下规则添加到配置了我的代理的.htaccess文件中:

# ALWAYS ALLOW PREFLIGHT REQUESTS (COUCHDB FORBIDS THIS RESPONSE FOR _bulk_docs)
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=204,L]

# Continue with RewriteRules for the CouchDB URLs you want to proxy
# plus whatever authorization headers you might want to add
RewriteRule db/(.*) http://couch.url:5984/database/$1 [P]

第一个RewriteRule捕获所有OPTIONS个请求并返回一个空白204,告诉客户端可以继续执行他们的CORS POST请求。如果不是这种情况,OPTIONS请求将转发给CouchDB,CouchDB将回复405.无论您在CouchDB配置中采用何种方法,都会执行此操作。

希望这可以帮助您解决具体案例。