我已经搜寻了近两个星期的问题答案。我有一个内置于web2py的简单系统。注意:我并不是Python的资深人士。我正在尝试使用web2py rest api将数据发布到数据库。如果我运行curl命令,则数据库表将更新,其余的将返回新添加的行的ID。这是理想的结果。但是,如果我尝试使用ajax请求执行相同的操作,则该请求将成功运行,但其余请求返回一个空对象,并且不会更新数据库。我添加了一个CORS包装器类,该类使我能够克服跨域问题。但是我不确定这是否同时阻止数据库更新等。还要注意,我也将数据(在ajax调用中)格式化为json对象,但是仍然没有。请在下面找到所有代码。

最重要:我收到以下消息-对预检请求的响应未通过访问控制检查:请求的资源上不存在“ Access-Control-Allow-Origin”标头。

任何/所有帮助都非常感谢你们。谢谢 :)

#Web2py model
db.define_table(‘myboard',
#Field('userid','reference auth_user'),
    Field('userid',db.auth_user,default=auth.user_id),
Field('title',requires=IS_LENGTH(100,1),label=“Board Title"),
Field(‘idea_a',requires=IS_LENGTH(75,1),label=“Idea A"),
Field(‘idea_b',requires=IS_LENGTH(75,1),label=“Idea B"),
Field('description','text',requires=IS_LENGTH(250,1),label=“Board Description"),
Field('contributors','integer',default='0'),
    Field('status','integer',writable=False,readable=False,default='1'), #1=draft, 2=public
Field('created_on','datetime',writable=False,default=request.now))


#Web2py controllers
def CORS(f):
"""
Enables CORS for any action
"""
def wrapper(*args, **kwargs): #*args, **kwargs
    if request.env.http_origin:
        response.headers['Access-Control-Allow-Origin'] = request.env.http_origin
        response.headers['Access-Control-Allow-Credentials'] = "true";
        response.headers['Access-Control-Allow-Headers'] = "Authorization,Content-Type,data";
        return dict()
    return f(*args, **kwargs)
return wrapper


auth.settings.allow_basic_login = True
@CORS
@request.restful()
def api():
from gluon.serializers import json
response.view = 'generic.'+request.extension
def GET(*args,**vars):
    patterns = 'auto'
    parser = db.parse_as_rest(patterns,args,vars)
    if parser.status == 200:
        return dict(content=parser.response)
    else:
        raise HTTP(parser.status,parser.error)
def POST(table_name,**vars):
    return json(db[table_name].validate_and_insert(**vars))
    return dict()
def PUT(table_name,record_id,**vars):
    return db(db[table_name]._id==record_id).update(**vars)
def DELETE(table_name,record_id):
    return db(db[table_name]._id==record_id).delete()
return dict(GET=GET, PUT=PUT, POST=POST,  DELETE=DELETE)


//CURL COMMAND - This Works!

curl -i --user somename@gmail.com:thepassword -H Accept:application/json -X POST http://127.0.0.1:8000/cc/default/api/myboard.json -H Content-Type: application/json -d 'userid=2&title=THE_TITLE&description=THE_DESCRIP&idea_a=THE 1st idea&idea_b=THE 2nd idea’


//AJAX CALL - Doesn't Work :(

var userid = 2;
var title = "THE_TITLE_HERE";
var description = "THE_DESCRIPTION_HERE"
var idea_a = "THE 1st idea";
var idea_b = "THE 2nd idea";


var userID = ’somename@gmail.com';
var password = ’thepassword';

var theData = "userid=2&title="+title+"&description="+description+”&idea_a=“+ideaA+”&idea_b=“+ideaB;

$.ajax({
    type: 'POST',
    headers: {"Authorization": "Basic " + btoa(userID + ":" + password)},
    url: "http://127.0.0.1:8000/cc/default/api/myboard.json",
    contentType:  "application/json; charset=utf-8",
    data: theData,
    success: function (data,textStatus,jqXHR) {
        alert(textStatus);
        console.log(data);
    },
    error: function(){
        alert("Cannot get data");
    }
});


数据库表未更新,但是请求成功运行。每次返回一个空对象。

最佳答案

您的wrapper函数将调用return dict(),该函数在调用f()之前执行,因此,修饰后的api函数永远不会被调用。只需删除该行。

另外,请注意,根据Ajax请求的性质,浏览器可能会首先创建preflight request。因此,您的装饰器代码将需要使用appropriate headers检测并响应此类请求。

关于javascript - 无法通过Ajax将数据发布到Web2py Rest API-可能出现CORS问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37806801/

10-09 00:50
查看更多