Ajax跨域调用问题及解决方案
Ajax跨域调用问题是一个老问题了,那究竟什么是跨域调用呢?先简单的解释一下:假如我们有一个网页是:http://saleservices.58corp.com:8081/,我们在这个页面调用接口:http://saleservices.58corp.com:8081/cookie来获取用户的基本信息的时候,就会报这个错误了。原因就是,调用的接口和当前页不在一个域名下。而网上也有很多解决这个的方法,如:http://blog.csdn.net/fdipzone/article/details/46390573/ 和http://www.cnblogs.com/Darren_code/p/cors.html。
而我们用的是Tornado框架下的python+js来做相应的处理的,所以暂且不管其他语言的解决办法了,现在以我的解决思路来分析一下:
一, JSONP方案
JSONP方法是一种非官方方法,而且这种方法只支持GET方式,不如POST方式安全。即使使用jquery的jsonp方法,type设为POST,也会自动变为GET。当然我也尝试了一下,将Post调用改成JSONP的方法,代码如下:
//post ajax调用
function postList(obj) {
url = obj.url;
datas = obj.datas;
func = obj.func;
$.ajax({
type : "POST",
url : url,
data : datas,
dataType : "JSONP",
success : function(data) {
func(data);
if (data.errno != 0) {
alert('对不起!' + ' ' + data.error);
}
}
});
}
当然在使用过程中虽然不报跨域调用的错误了,但是有的时候json格式的字符串会报格式错误,查了半天也没有找到特别好的解决办法。
二,设置"Access-Control-Allow-Origin"
在网上查找了这个问题,很多网站都提到设置header信息中的"Access-Control-Allow-Origin",如:http://www.cnblogs.com/mahatmasmile/archive/2013/03/29/2989505.html,于是想到既然其他的语言可以设置header信息,Tornado也肯定可以设置相关的信息了哟!
结果发现设置起来非常简单,就一句话:self.set_header("Access-Control-Allow-Origin", "*"),在需要跨域调用的接口中添加上这一句话,就可以完美地解决ajax跨域调用的问题。
如下所示:
def post(self):
'''
保存授权更新或是删除用户权限
@param serid:要操作的用户id
@param opertype:要执行的操作:del or update
@param uright:用户新权限
@param apres:授权结果
@return 返回执行情况
'''
self.set_header("Access-Control-Allow-Origin", "*")
userid=self.get_argument('userid', '')
userid=userid.encode("utf-8").replace("\'", "").replace('\"', "")
optype=self.get_argument('opertype', '')
optype=optype.encode("utf-8").replace("\'", "").replace('\"', "")
uright=self.get_argument('uright', '')
uright=uright.encode("utf-8").replace("\'", "").replace('\"', "")
apres=self.get_argument('apres', '')
apres=apres.encode("utf-8").replace("\'", "").replace('\"', "")
#根据操作类型进行不同的操作
udo=UserDetailOperations()
if optype=="del":
res=udo.delservice(userid)
if res==0:
apires={"errno":1000,"error":"删除用户:"+userid+"失败"}
else:
apires={"errno":0,"data":{"userid":userid,"opertype":optype}}
else:
userdic={"userid":userid,"uright":uright,"apres":apres}
ures=udo.updateuser(userdic)
if ures==0:
apires={"errno":1000,"error":"更新用户:"+userid+"失败"}
else:
apires={"errno":0,"data":{"userid":userid,"opertype":optype}}
self.write(apires)