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.
我对此有所了解并使用了解决方案完成了以下操作:
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
我只是不明白我做错了什么!
答案 0 :(得分:1)
如果您希望得到回复,则应使用“200”响应代码,而不是204,因为这是“无内容”响应。有关详细信息,请参阅W3C Spec
9.7删除
DELETE方法请求源服务器删除Request-URI标识的资源。可以覆盖此方法 通过源服务器上的人为干预(或其他方式)。该 客户不能保证已经进行了操作, 即使从原始服务器返回的状态代码指示了这一点 该行动已成功完成。但是,服务器应该 除非在给出答复时,否则不表示成功 打算删除资源或将其移动到无法访问的位置。
如果响应包含描述状态的实体,则成功响应应为200(OK),如果操作未包含,则应为202(已接受) 尚未颁布,或204(无内容),如果该行动已经颁布 但是回复不包括实体。
如果请求通过缓存并且Request-URI标识了一个或多个当前缓存的实体,那么这些条目应该是 被视为陈旧。对此方法的响应不可缓存。
答案 1 :(得分:0)
您在响应标头中看到Access-Control-Allow-Origin: *
。这来自... / restify / lib / router.js preflight()方法。评论指出“用户需要定义自己的.opts处理程序”。
答案 2 :(得分:0)
使用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);
});
答案 3 :(得分:-2)
只需设置标题res.setHeader('Access-Control-Allow-Methods', '*');
以下是答案:https://github.com/mcavage/node-restify/issues/296#issuecomment-12333568