title: Bottle Py: Enabling CORS for jQuery AJAX requests
body: <p>I'm working on a RESTful API of a web service on the Bottle Web Framework and want to access the resources with jQuery AJAX calls.</p>
  
  <p>Using a REST client, the resource interfaces work as intended and properly handle GET, POST, ... requests. But when sending a jQuery AJAX POST request, the resulting OPTIONS preflight request is simply denied as '405: Method not allowed'.</p>
  
  <p>I tried to enable CORS on the Bottle server - as described here: <a href="http://bottlepy.org/docs/dev/recipes.html#using-the-hooks-plugin" rel="noreferrer">http://bottlepy.org/docs/dev/recipes.html#using-the-hooks-plugin</a>
  But the <strong>after_request hook</strong> is never called for the OPTIONS request.</p>
  
  <p>Here is an excerpt of my server:</p>
  
  <pre><code>from bottle import Bottle, run, request, response
  import simplejson as json
  
  app = Bottle()
  
  @app.hook('after_request')
  def enable_cors():
      print "after_request hook"
      response.headers['Access-Control-Allow-Origin'] = '*'
      response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, OPTIONS'
      response.headers['Access-Control-Allow-Headers'] = 'Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token'
  
  @app.post('/cors')
  def lvambience():
      response.headers['Content-Type'] = 'application/json'
      return "[1]"
  
  [...]
  </code></pre>
  
  <p>The jQuery AJAX call:</p>
  
  <pre><code>$.ajax({
      type: "POST",
      url: "http://192.168.169.9:8080/cors",
      data: JSON.stringify( data ),
      contentType: "application/json; charset=utf-8",
      dataType: "json",
      success: function(data){
          alert(data);
      },
      failure: function(err) {
          alert(err);
      }
  });
  </code></pre>
  
  <p>The server only logs a 405 error:</p>
  
  <pre><code>192.168.169.3 - - [23/Jun/2013 17:10:53] "OPTIONS /cors HTTP/1.1" 405 741
  </code></pre>
  
  <p>$.post does work, but not being able to send PUT requests would defeat the purpose of a RESTful service.
  So how can I allow the OPTIONS preflight request to be handled?</p>