2013-02-04 46 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); 
    });