2013-02-04 39 views
1

CORS开始炒我的脑子了。除了一种方法之外,现在一切都很好。我正在构建一个应用程序,在前端使用backbone,在后端使用node.js/restify。该server.coffee看起来是这样的:Restify删除方法

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 

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

回答

1

如果您希望得到答复,您应该使用'200'响应代码,而不是204,因为这是无内容响应。见W3C Spec的细节

9.7 DELETE

The DELETE method requests that the origin server delete the resource identified by the Request-URI. This method MAY be overridden by human intervention (or other means) on the origin server. The client cannot be guaranteed that the operation has been carried out, even if the status code returned from the origin server indicates that the action has been completed successfully. However, the server SHOULD NOT indicate success unless, at the time the response is given, it intends to delete the resource or move it to an inaccessible location.

A successful response SHOULD be 200 (OK) if the response includes an entity describing the status, 202 (Accepted) if the action has not yet been enacted, or 204 (No Content) if the action has been enacted but the response does not include an entity.

If the request passes through a cache and the Request-URI identifies one or more currently cached entities, those entries SHOULD be treated as stale. Responses to this method are not cacheable.

+0

嗯。尽管这些代码实际上从未被外观所执行,所以这可能不是问题。尝试了 – andy

0

你看到的响应头Access-Control-Allow-Origin: *。这是来自.../restify/lib/router.js preflight()方法。评论状态“用户将需要定义他们自己的.opts处理程序”。

0

使用server.opts方法WIRTE自己的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); 
    });