【问题标题】:Restify Delete MethodRestify 删除方法
【发布时间】:2017-05-14 20:50:44
【问题描述】:

CORS 开始有点煎熬我的大脑。现在一切都很好,除了一种方法。我正在构建一个应用程序,前端带有主干,后端带有 node.js/restify。 server.coffee 看起来像这样:

server.get '/todos', todos.find_all
server.get '/todos/:id', todos.find_by_id
server.del '/todos/:id', todos.delete

每当主干中的模型调用destroy 时,我都会收到这个相当烦人的错误:

MLHttpRequest cannot load http://localhost:8080/todos/. Method DELETE is not allowed by Access-Control-Allow-Methods.

我读到了一点,并使用 restify 完成了以下操作:

unknownMethodHandler = (request, response) ->
    if(request.method.toLowerCase() == 'options')
        allowHeaders = ['Accept', 'Accept-Version', 'Content-Type', 'Api-Version']

        if(response.methods.indexOf('OPTIONS') == -1) then response.methods.push('OPTIONS')

        response.header 'Access-Control-Allow-Credentials', true
        response.header 'Access-Control-Allow-Headers', allowHeaders.join(', ')
        response.header 'Access-Control-Allow-Methods', ['GET', 'DELETE', 'TEST!']
        response.header 'Access-Control-Allow-Origin', request.headers.origin

        response.send 204
    else
        response.send new restify.MethodNotAllowedError()

server.on 'MethodNotAllowed', unknownMethodHandler

但即便如此,我还是把它作为响应头:

HTTP/1.1 204 No Content
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version
Access-Control-Allow-Methods: GET, OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: X-Api-Version, X-Request-Id, X-Response-Time
Connection: Keep-Alive
Date: Mon, 04 Feb 2013 12:24:25 GMT
Server: restify
X-Request-Id: fbd4e15a-a22e-48b6-bf5c-a46b94926748
X-Response-Time: 0

我只是不明白我做错了什么!

【问题讨论】:

    标签: ajax node.js backbone.js restify


    【解决方案1】:

    如果您期待响应,则应使用“200”响应代码,而不是 204,因为那是无内容响应。详情见W3C Spec

    9.7 删除

    DELETE 方法请求源服务器删除由 Request-URI 标识的资源。此方法可能被覆盖 通过原始服务器上的人工干预(或其他方式)。这 客户不能保证操作已经执行, 即使从源服务器返回的状态码表明 动作已成功完成。但是,服务器应该 不表示成功,除非在给出响应时,它 打算删除资源或将其移动到无法访问的位置。

    如果响应包含描述状态的实体,则成功的响应应该是 200(OK),如果操作没有,则应该是 202(接受) 尚未制定,或 204(无内容),如果已制定行动 但响应不包含实体。

    如果请求通过缓存并且 Request-URI 标识了一个或多个当前缓存的实体,则这些条目应该 被视为陈旧。对此方法的响应不可缓存。

    【讨论】:

    • 嗯。尽管从外观上看,该代码实际上从未真正执行过,因此这可能不是问题。
    【解决方案2】:

    您会在响应标头中看到 Access-Control-Allow-Origin: *。这来自 .../restify/lib/router.js preflight() 方法。评论指出“用户需要定义自己的 .opts 处理程序”。

    【讨论】:

      【解决方案3】:

      使用 server.opts 方法为 OPTIONS 请求编写您自己的处理程序。 以下是您可以使用的示例。

      同时告诉我你是否在从浏览器发出请求时使用 set-credentials 标志为 true。在这种情况下,这个句柄必须响应访问 cookie。

      在下面的示例中,我返回允许的来源以进行完全匹配。 您也可以将其调整为子字符串匹配。但始终返回在响应标头“Access-Control-Allow-Origin”中的请求标头来源中找到的确切值。这是一个很好的做法。

      server.opts('/api/(.)*', (req, res) => {
      const origin = req.header('origin');
      const allowedOrigins = ['example.com', 'example.org'];
      if (allowedOrigins.indexOf(origin) === -1) {
          //origin is not allowed
          return res.send(405);
      }
      //set access control headers to allow the preflight/options request
      res.setHeader('Access-Control-Allow-Origin', header);
      res.setHeader('Access-Control-Allow-Headers', 'Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version');
      res.setHeader('Access-Control-Allow-Methods', 'GET,POST,PUT,PATCH,DELETE,OPTIONS');
      
      // Access-Control-Max-Age header catches the preflight request in the browser for the desired
      // time. 864000 is ten days in number of seconds. Also during development you may want to keep
      
      
         // this number too low e.g. 1.
          res.setHeader('Access-Control-Max-Age', 864000);
          return res.send(200);
        });
      

      【讨论】:

        【解决方案4】:

        只需设置标题res.setHeader('Access-Control-Allow-Methods', '*');

        这里是答案:https://github.com/mcavage/node-restify/issues/296#issuecomment-12333568

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-12-31
          • 2015-01-27
          • 2013-04-25
          • 2011-05-21
          • 2020-07-18
          • 1970-01-01
          • 2020-01-05
          • 1970-01-01
          相关资源
          最近更新 更多