cross origin calls working, but not OPTIONS

1,483 views
Skip to first unread message

Ryan Kelly

unread,
Feb 5, 2013, 6:17:43 PM2/5/13
to res...@googlegroups.com
test
Message has been deleted

Ryan Kelly

unread,
Feb 5, 2013, 7:02:13 PM2/5/13
to res...@googlegroups.com
(sorry, but my posts keep getting deleted)

I'm still not able to get this working. Here is what I have.

restify 2.1.1

// server.js
...
server.use(restify.acceptParser(server.acceptable));
server.use(restify.queryParser());
server.use(restify.bodyParser());
server.use(restify.authorizationParser());
//server.use(authenticate);
server.use(restify.CORS());
server.use(restify.fullResponse());
...

Message has been deleted
Message has been deleted
Message has been deleted

Ryan Kelly

unread,
Feb 5, 2013, 7:14:43 PM2/5/13
to res...@googlegroups.com
Google keeps deleting my sample code for some reason...

but, essentially what I do is make a x-domain curl request, specifying the origin (which works fine), and the OPTIONS flag, as well as setting the 'access-control-request-method' to POST.

I get a 405 response from my server, with an 'Allow' header that contains GET, POST. For the life of me, I cannot get my restify api to accept the OPTIONS method.

Any idea what I could be doing wrong?

Mark Cavage

unread,
Feb 5, 2013, 9:44:25 PM2/5/13
to res...@googlegroups.com
Hi Ryan,

What do you mean "the OPTIONS flag" and POST?  Can you show me some sample requests?

Short-answer: CORS is really complicated, and you'll only send OPTIONS if you need to preflight (POST does not usually merit a preflight, unless the content-type is json or related).   And the headers won't show up unless it's actually a CORS request in the response.  Lastly, you probably don't want both the cors and fullResponse plugin.

m

--
You received this message because you are subscribed to the Google Groups "restify" group.
To unsubscribe from this group and stop receiving emails from it, send an email to restify+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Ryan Kelly

unread,
Feb 5, 2013, 10:22:28 PM2/5/13
to res...@googlegroups.com
Hi Mark, I just got it working. I'm fairly new to node so this was a combination of things. 

  • I only have server.use(restify.CORS()); in there now, although after I got it working and added fullResponse(); back in - everything would still function. 
  • In my addVenue operation, I added the following headers:
    •   res.header("Access-Control-Allow-Origin", "*"); 
    •   res.header("Access-Control-Allow-Headers", "X-Requested-With");
    •   res.header("Access-Control-Allow-Methods", "*");
  • But the kicker I think was this (and it wasn't clear to me that this was for sure still needed)
    • // venue methods
    • server.opts('/venues', function(req, res) {
    •     // taken care of the CORS stuff, so just return OK.
    •     res.send(200);
    • });
Does all of that look right to you or is there a more appropriate way? If nothing else, I'd like to be able to set my res.headers globally for my entire API - is that possible?

By the way, GREAT framework! It has saved me a ton of time and I was able to build a RESTful API very quickly so far.
Thank you for your hard work.

Mark Cavage

unread,
Feb 6, 2013, 10:56:21 AM2/6/13
to res...@googlegroups.com
Hey Ryan,

Ok, I looked into this, there was a bug in restify, which is now fixed here(https://github.com/mcavage/node-restify/commit/76c359ee6884ac30ee003dfc5f9119373e43f4fa).  You can work around it with your own 'opts' handler, but restify should have handled this case for you.  

As to your question about global headers, yeah, do something like this (early on):

server.use(function myResponseHeaders(req, res, next) {
    res.once('header', function () {
        res.setHeader('foo', 'bar');
        ...
    });
    next();
});

And glad it's working out for you on the whole - sorry about the CORS mixup.

m

--

Ryan Kelly

unread,
Feb 6, 2013, 11:50:06 PM2/6/13
to res...@googlegroups.com
Hey Mark, this approach should support the DELETE method as well - correct?

When I'm trying to delete, I don't get hung up on CORS, but instead the DELETE method.

// in venues.js
exports.deleteById = function(req, res) {
  res.header("Access-Control-Allow-Origin", "*"); 
  res.header("Access-Control-Allow-Headers", "*");
  res.header("Access-Control-Allow-Methods", "*");
....

// trace
  1. Request URL:
  2. Request Method:
    OPTIONS
  3. Status Code:
    200 OK
  4. Request Headersview parsed
    1. OPTIONS /venues/my-venue HTTP/1.1 Host: localhost:3000 Connection: keep-alive Access-Control-Request-Method: DELETE Origin: http://localhost:3001 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17 Access-Control-Request-Headers: accept, origin Accept: */* Referer: http://localhost:3001/ Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
  5. Response Headersview parsed
    1. HTTP/1.1 200 OK Access-Control-Allow-Origin: * Access-Control-Expose-Headers: api-version, content-length, content-md5, content-type, date, request-id, response-time Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time Access-Control-Allow-Methods: GET, POST Connection: Keep-Alive Date: Thu, 07 Feb 2013 04:46:52 GMT Server: restify Request-Id: 63f52960-70e1-11e2-b28f-61793ef6abac Response-Time: 1 Transfer-Encoding: chunked

Mark Cavage

unread,
Feb 7, 2013, 10:35:17 AM2/7/13
to res...@googlegroups.com
Hey Ryan,

Not sure what you mean here - you mean DELETE isn't supported by your app, or t's not showing up in allow-methods, or something else?

m

--

Ryan Kelly

unread,
Feb 7, 2013, 10:48:50 AM2/7/13
to res...@googlegroups.com
correct, I want to support the DELETE operation but according to my server response headers (Access-Control-Allow-Methods) - it appears it only allows GET and POST. 

in my server.js I have a route defined as this...

// server.js
server.del('/venues/:id', venues.deleteById);

it maps to this...

// venues.js
exports.deleteById = function(req, res) {
  res.header("Access-Control-Allow-Origin", "*"); 
  res.header("Access-Control-Allow-Headers", "*");
  res.header("Access-Control-Allow-Methods", "*");
  
  var v = string(req.params.id).slugify().s;
Venue.findByIdAndRemove(v, function(err, venue) {
      // problems
      if (err) return res.send(new restify.RestError(err));
      // found
      if (venue) return res.send(200, "{ 'message' : '" + v + " was removed.'}");
      // not found
      return res.send(new restify.ResourceNotFoundError(v + " was not found."));
});
}

Mark Cavage

unread,
Feb 7, 2013, 11:10:34 AM2/7/13
to res...@googlegroups.com
Hey Ryan,

Can you send me some more code context - this works for me out of #master (with that fix from yesterday): https://gist.github.com/mcavage/4731960

m

--

Ryan Kelly

unread,
Feb 7, 2013, 7:39:15 PM2/7/13
to res...@googlegroups.com
hmmm, your example worked for me too. maybe because I don't have next(); specified. I'll do a little more troubleshooting and see what it might be.

Ryan Kelly

unread,
Feb 8, 2013, 2:40:20 PM2/8/13
to res...@googlegroups.com
really strange, I updated some code and my experiences on the gist - https://gist.github.com/mcavage/4731960

Mark Cavage

unread,
Feb 9, 2013, 12:13:23 PM2/9/13
to res...@googlegroups.com
Hey Ryan,

It's because of 

// venue methods
server.get('/venues', venues.findAll);
server.get('/venues/:id', venues.findById);
server.post('/venues', venues.addVenue);

server.del('/venues/:id', venues.deleteById);

/venues and /venues/:id are two different URLs, and restify handles preflight differently on them. In your curl example you're doing POST /venues/foo which isn't actually a registered route.

m

On Fri, Feb 8, 2013 at 11:40 AM, Ryan Kelly <ryan.ke...@gmail.com> wrote:
really strange, I updated some code and my experiences on the gist - https://gist.github.com/mcavage/4731960

--

Ryan Kelly

unread,
Feb 9, 2013, 12:21:50 PM2/9/13
to res...@googlegroups.com
oh! man, i'm sorry to spend so much of your time on this. I should have caught that. Still learning this environment... thanks!
Reply all
Reply to author
Forward
0 new messages