1

Having some annoying issues making AJAX calls simply because almost every browser these days is making an OPTIONS call to the server before the actual AJAX call.

Since I am using Play! 2.0, is there any easy way to make a wildcard response to any route using the OPTIONS method?

For instance, in my routes do something like: OPTIONS /* controllers.Options.responseDef

Yes I am aware that the new Play! doesn't have a wildcard built-in, but there needs to be a solution for this since all browsers are increasingly calling OPTIONS before AJAX calls.

miken32
  • 42,008
  • 16
  • 111
  • 154
crockpotveggies
  • 12,682
  • 12
  • 70
  • 140

2 Answers2

2

Not quite a wildcard, but you can use a route which spans several slash-segments:

OPTIONS   /*wholepath     controllers.Options.responseDef(wholepath)
OPTIONS   /               controllers.Options.responseDef

It should match all the requests:

OPTIONS    /a
OPTIONS    /a/b
OPTIONS    /a/b/c

Note: that's from the top of my head, so maybe you'll need to polish it. I can't check it now by myself.

Check the section Dynamic parts spanning several / of the manual.

crockpotveggies
  • 12,682
  • 12
  • 70
  • 140
biesior
  • 55,576
  • 10
  • 125
  • 182
  • Interesting, is *wholepath a recently added feature? I just upgraded to 2.0.1 this seems like a "fresh" feature ;) I'll test it out and let you know if it works :) – crockpotveggies Jun 30 '12 at 21:51
  • Nope, it's available since 2.0 (0) I think, don't remember, what's more important I just realised, we can use it to solve other routing problems, ie. for avoiding redundant trailing slashes: https://groups.google.com/d/msg/play-framework/yGCubIgnP2o/lFOUl0Ccvw8J :) BTW of course `wholepath` is just a name of variable, you can use any other name, the most important is asterisk before the name `*some` instead of colon `:some` – biesior Jun 30 '12 at 22:27
  • Seems to be something wrong here...that route (and regex routes) won't compile with `Cannot use a method returning play.api.mvc.SimpleResult` – crockpotveggies Jul 01 '12 at 22:03
  • weird, I was testing this and it worked, but it was tested with Java actions. is your `responseDef` valid Play's action ? – biesior Jul 01 '12 at 22:08
  • Correct I just added a `def` to another controller and referenced it as usual. I am going to try an upgrade to `2.0.2` and see if it fixes it. – crockpotveggies Jul 01 '12 at 22:15
  • I was testing it with `2.0.1` and `2.0.2`, in this topic there should not be any differences between the versions. – biesior Jul 01 '12 at 22:29
  • Ah this is my mistake, a typo. I screwed up the `= Action {` bit. All good :) – crockpotveggies Jul 01 '12 at 22:40
1

A very clean way to have a single controller endpoint match all OPTIONS requests is to override the onRouteRequest method of Play's Global object. The following version of onRouteRequest will route all requests to a single endpoint named OptionsController.options.

import play.api.mvc._

...

override def onRouteRequest(request: RequestHeader): Option[Handler] = {
  request.method match {
    case "OPTIONS" => Some(OptionsController.options)
    case _ => super.onRouteRequest(request)
  }
}
msiebert
  • 45
  • 5