jquery - Bottle Py : Enabling CORS for jQuery AJAX requests

标签 jquery ajax cors bottle

我正在 Bottle Web 框架上开发 Web 服务的 RESTful API,并希望通过 jQuery AJAX 调用访问资源。

使用 REST 客户端,资源接口(interface)按预期工作并正确处理 GET、POST...请求。但是,当发送 jQuery AJAX POST 请求时,生成的 OPTIONS 预检请求会被简单地拒绝为“405:方法不允许”。

我尝试在 Bottle 服务器上启用 CORS - 如下所述:http://bottlepy.org/docs/dev/recipes.html#using-the-hooks-plugin 但是 OPTIONS 请求永远不会调用 after_request Hook

这是我的服务器的摘录:

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]"

[...]

jQuery AJAX 调用:

$.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);
    }
});

服务器仅记录 405 错误:

192.168.169.3 - - [23/Jun/2013 17:10:53] "OPTIONS /cors HTTP/1.1" 405 741

$.post 确实有效,但无法发送 PUT 请求将违背 RESTful 服务的目的。 那么我怎样才能允许处理 OPTIONS 预检请求呢?

最佳答案

安装处理程序而不是 Hook 。

我过去有两种互补的方法来完成此操作:装饰器或 Bottle 插件。我将向您展示两者,您可以决定其中之一(或两者)是否适合您的需求。在这两种情况下,总体思路是:处理程序在将响应发送回客户端之前拦截响应,插入 CORS header ,然后继续返回响应。

方法一:安装每路由(装饰器)

当您只想在某些路由上运行处理程序时,此方法更合适。只需装饰您希望其执行的每条路线即可。这是一个例子:

import bottle
from bottle import response

# the decorator
def enable_cors(fn):
    def _enable_cors(*args, **kwargs):
        # set CORS headers
        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'

        if bottle.request.method != 'OPTIONS':
            # actual request; reply with the actual response
            return fn(*args, **kwargs)

    return _enable_cors


app = bottle.app()

@app.route('/cors', method=['OPTIONS', 'GET'])
@enable_cors
def lvambience():
    response.headers['Content-type'] = 'application/json'
    return '[1]'

app.run(port=8001)

方法2:全局安装(Bottle插件)

如果您希望处理程序在所有或大部分路由上执行,那么此方法是更好的选择。你只需define a Bottle plugin一次,Bottle 会在每条路线上自动为您调用;无需为每个装饰器指定一个。 (请注意,您可以使用路由的 skip 参数来在每个路由的基础上避免此处理程序。)以下是与上面的示例相对应的示例:

import bottle
from bottle import response

class EnableCors(object):
    name = 'enable_cors'
    api = 2

    def apply(self, fn, context):
        def _enable_cors(*args, **kwargs):
            # set CORS headers
            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'

            if bottle.request.method != 'OPTIONS':
                # actual request; reply with the actual response
                return fn(*args, **kwargs)

        return _enable_cors


app = bottle.app()

@app.route('/cors', method=['OPTIONS', 'GET'])
def lvambience():
    response.headers['Content-type'] = 'application/json'
    return '[1]'

app.install(EnableCors())

app.run(port=8001)

关于jquery - Bottle Py : Enabling CORS for jQuery AJAX requests,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17262170/

相关文章:

javascript - JQuery 预检请求 CORS

c# - 在查询字符串中使用点 ("."时未设置 CORS header )

javascript - HTML:像 SVG 一样清晰地保留使用 jQuery 进行的样式更改(例如,宽度、位置)?

javascript - Jquery 如何计算来自不同 div 的复选框

javascript - Ajax Success 启动失败

javascript - 在另一个函数成功结束后调用另一个函数

ajax - jquery/ajax 加载脚本 - 最佳实践

javascript - 无法读取未定义的属性 'hasTime'

javascript - 自定义按钮数量tinymce

jquery - 缺少 CORS header 'Access-Control-Allow-Origin'