1

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

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

4

4 回答 4

1

如果您期待响应,则应使用“200”响应代码,而不是 204,因为那是无内容响应。有关详细信息,请参阅W3C 规范

9.7 删除

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

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

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

于 2013-02-04T14:13:15.623 回答
0

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

于 2013-07-11T11:45:03.297 回答
0

Use server.opts method to wirte your own handler for OPTIONS request. Below is the example you can use.

Also tell me if you are using set-credentials flag to true while making request from the browser. This handle in that case would have to respond with access cookies.

In the example below, I am returning the allowed origin for exact match. You can tweak it to be substring match also. But always return the exact value as found in request header origin in the response header 'Access-Control-Allow-Origin'. Its a good practice.

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);
  });
于 2017-05-13T19:53:14.977 回答
-2

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

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

于 2014-12-07T10:44:32.540 回答