Cors实现跨域ajax,基本原理:客户端不变,服务器端在返回响应数据时,添加响应头让浏览器允许其通过, Cors实现跨域ajax很简便,但不是所有浏览器都支持;sonp实现跨域,只能get请求;
一、浏览器发送简单请求:服务器直接添加响应头实现跨域 问:什么是简单请求? 答:请求方式为head、get、post,且请求头信息满足条件 客户端发送正常的ajax请求: html <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<input type="button" value="Ajax" onclick="DoAjax();" />
<script src="sss/jquery-1.12.4.min.js"></script>
<script>
function DoAjax(){
$.ajax({
url:'http://ajax2.com:8888/index',
type:'POST',
data:{'k1':'v1'},
success:function(arg){ console.log(arg); },
});
};
</script>
</body>
</html> 服务器端添加响应头实现跨域ajax: #!/usr/bin/env python
# -*- coding:utf-8 -*-
import tornado.ioloop
import tornado.web
class IndexHandler(tornado.web.RequestHandler):
def get(self):
self.write("ajax2_get")
def post(self, *args, **kwargs):
self.set_header('Access-Control-Allow-Origin','http://ajax1.com:8001') # 添加响应头,允许指定域名的跨域请求
self.write("ajax2_post")
# 路径解析
settings = {
"template_path":"views",
"static_path":"statics",
"static_url_prefix":"/sss/",
}
# 二级路由,先匹配域名,
application = tornado.web.Application([
(r"/index",IndexHandler),
],**settings)
# 开启服务器,监听
if __name__ == "__main__":
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
二、浏览器发送复杂请求,需要预检,通过才可发送正式请求 1、浏览器首先自动发送一个option请求预检,如果预检通过,返回可接受的访问方式, 2、按可接受的访问方式进行正式的请求, 注意:无论是预检还是正式的请求,都是以简单请求为基础的,每一次都需要允许域名跨域的响应头, s_py #!/usr/bin/env python
# -*- coding:utf-8 -*-
import tornado.ioloop
import tornado.web
class IndexHandler(tornado.web.RequestHandler):
def get(self):
self.write("ajax2_get")
# 简单请求
def post(self, *args, **kwargs):
# 添加响应头,允许指定域名的跨域请求
# self.set_header('Access-Control-Allow-Origin','http://ajax1.com:8001,') # 可同时指定多个域名,用逗号隔开,
self.set_header('Access-Control-Allow-Origin','*') # *表示所有域名都可以进行跨域申请
self.write("ajax2_post")
# 复杂请求的预检
def options(self, *args, **kwargs):
self.set_header('Access-Control-Allow-Origin','*') # 指明允许请求的域名,可以是具体域名
self.set_header('Access-Control-Allow-Methods','PUT,DELETE') # 指明允许请求的方法,可多个,但不能是*,
self.set_header('Access-Control-Allow-Headers','h1,h2,') # 指明允许通过的header,有时客户端会设置,
# self.set_header('Access-Control-Max-Age',10) # 设置有效时间,秒
# 复杂请求
def put(self, *args, **kwargs):
self.set_header('Access-Control-Allow-Origin','*')
self.write('put')
# 路径解析
settings = {
"template_path":"views",
"static_path":"statics",
"static_url_prefix":"/sss/",
}
# 二级路由,先匹配域名,
application = tornado.web.Application([
(r"/index",IndexHandler),
],**settings)
# 开启服务器,监听
if __name__ == "__main__":
application.listen(8888)
tornado.ioloop.IOLoop.instance().start() c_html <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<input type="button" value="SimpleAjaxCors" onclick="DoSimpleAjax();" />
<input type="button" value="ComplexAjaxCors" onclick="DoComplexAjax();" />
<script src="sss/jquery-1.12.4.min.js"></script>
<script>
function DoSimpleAjax(){
$.ajax({
url:'http://ajax2.com:8888/index',
type:'POST',
data:{'k1':'v1'},
success:function(arg){ console.log(arg); },
});
};
function DoComplexAjax(){
$.ajax({
url:'http://ajax2.com:8888/index',
type:'PUT',
data:{'k1':'v1'},
headers:{'h1':'xxoo'}, <!--需要服务器端设置header-->
success:function(arg){ console.log(arg); },
});
};
三、cros方式发送跨域Ajax,默认不传递cookie,需要客户端携带cookie时,进行如下设置: (1)客户端设置:xhrFields:{withCredentials:'true'}, 表明携带cookie, (2)服务器端设置:self.set_header('Access-Control-Allow-Credentials','true') ,表明允许客户端携带cookie, 注意:允许携带cookie时,必须制定域名,不能用*, 另外:jsonp方式跨域,默认传递cookie, 分类: Ajax |