聊聊Ajax跨域
2021-06-20 15:03
标签:dex 代码 listen put 一个 val last -o write 由于浏览器的同源策略,使得发送请求的时候,只能给本域发送请求,不能跨域发送请求。对于Ajax请求来说,跨域浏览器是不允许的。原因不是不能发送,Ajax跨域的时候,确实发送了请求,并且收到了另一个域名的响应。但是浏览器会报错,默认情况下,Ajax不允许跨域,而script,img, iframe 允许跨域, 基本上通过src引用去发送请求的,都可以跨域。src请求相当于发送了一个GET请求 那么如何让Ajax可以跨域请求呢?今天介绍两种方案 什么是jsonp?jsonp是如何实现跨域请求的呢? 在前言中提到,对于Ajax提交的请求是不允许跨域,只能是本域请求,而浏览器允许具有src属性的元素跨域进行请求。那么是否可以借助src属性来帮助Ajax跨域呢? 答对了,这就是jsonp实现跨域请求的基本原理 优点:兼容性好,应用广泛 缺点:由于是src引用发送的请求,那么jsonp的请求只能是get请求,不能是其他的请求。 好了,说到这里,我们来看看,jsonp是如何跨域的 当客户端跨域请求时,服务端返回数据的时候,同时绑定一个标记,告诉浏览器这是跨域请求的数据,不要报错。当浏览器识别这个标示的时候,浏览器就不会报错了,这个表示就是加上一个响应头CORS。这样就实现了跨域请求。客户端请求与本域请求一样不变,服务端这是一个CORS响应头即可。 概念说明: 聊聊Ajax跨域 标签:dex 代码 listen put 一个 val last -o write 原文地址:http://www.cnblogs.com/yinhuanyi/p/7188791.html前言
JSONP
1 # Python write by yhy
2 import tornado.web
3 import tornado.ioloop
4
5 class IndexHandler(tornado.web.RequestHandler):
6 def get(self, *args, **kwargs):
7 self.write(‘func([11,22,33])‘)
8
9 # 说明一下这个‘static_url_prefix‘: ‘/statics/‘,的问题
10 settings = {
11 ‘template_path‘: ‘views‘,
12 ‘static_path‘: ‘statics‘,
13 ‘static_url_prefix‘: ‘/statics/‘,
14 }
15
16 application = tornado.web.Application([
17 (r‘/index‘, IndexHandler)
18 ], **settings)
19
20 if __name__ == ‘__main__‘:
21 application.listen(8002)
22 tornado.ioloop.IOLoop.instance().start()
1 DOCTYPE html>
2 html lang="en">
3 head>
4 meta charset="UTF-8">
5 title>Titletitle>
6 script src="/statics/jquery.js">script>
7 head>
8 body>
9 input type="button" value="Ajax" onclick="DoAjax();">
10 input type="button" value="JsonpAjax" onclick="DoJsonpAjax();">
11 script>
12 function func(arg) {
13 console.log(arg)
14 }
15
16 // Ajax
17 function DoAjax() {
18 $.ajax({
19 url: ‘http://127.0.0.1:8002/index‘,
20 type: ‘POST‘,
21 data: {‘k1‘: ‘v1‘},
22 success: function (arg) {
23 console.log(arg);
24 }
25 })
26 }
27
28 // JsonAjax
29 function DoJsonpAjax() {
30 var tag = document.createElement(‘script‘);
31 tag.src = "http://127.0.0.1:8002/index";
32 document.head.appendChild(tag);
33 document.head.removeChild(tag);
34 }
35 script>
36 body>
37 html>
1 DOCTYPE html>
2 html lang="en">
3 head>
4 meta charset="UTF-8">
5 title>Titletitle>
6 script src="/statics/jquery.js">script>
7 head>
8 body>
9 input type="button" value="Ajax" onclick="DoAjax();">
10 input type="button" value="JsonpAjax" onclick="DoJsonpAjax();">
11 script>
12 // 这里的func函数就是等待被调用,等待跨域请求返回的调用函数的字符串调用,一旦调用就会在这个函数中拿到跨域请求的参数。
13 function func(arg) {
14 console.log(arg)
15 }
16
17 // Ajax
18 function DoAjax() {
19 $.ajax({
20 url: ‘http://127.0.0.1:8002/index‘,
21 type: ‘POST‘,
22 data: {‘k1‘: ‘v1‘},
23 success: function (arg) {
24 console.log(arg);
25 }
26 })
27 }
28
29 // JsonAjax
30 function DoJsonpAjax() {
31 // 基于jquery的Ajax的跨域请求,只要指明dataType为‘jsonp‘,那么就相当于创建了一个带有src的script标签,跨域请求通常返回一个函数,这个函数包裹在
32 $.ajax({
33 url: ‘http://127.0.0.1:8002/index‘,
34 dataType: ‘jsonp‘,
35 jsonpCallBack: ‘func‘
36
37 })
38 }
39 script>
40 body>
41 html>
1 DOCTYPE html>
2 html lang="en">
3 head>
4 meta charset="UTF-8">
5 title>Titletitle>
6
7 script src="../statics/jquery.js">script>
8 head>
9 body>
10 input type="button" onclick="AjaxJsonp();" value="Ajax" >
11 input type="button" onclick="jQueryAjaxJsonp();" value="jqueryAjax">
12
13 script>
14 function getData(arg) {
15 console.log(arg);
16 }
17 function AjaxJsonp() {
18 var tag = document.createElement(‘script‘);
19 tag.src = ‘http://yhycn.com:8002/index?callback=getData‘;
20 document.head.appendChild(tag);
21 document.head.removeChild(tag);
22 }
23 function jQueryAjaxJsonp() {
24 $.ajax({
25 url: ‘http://yhycn.com:8002/index‘,
26 dataType: ‘jsonp‘,
27 // 下面的jsonp: ‘callback‘,jsonCallBack: ‘getData‘, 相当于在请求的url中指定/index?callback=getData
28 jsonp: ‘callback‘,
29 jsonCallback: ‘getData‘,
30 })
31 }
32 script>
33 body>
34 html>
CORS:跨域资源共享(Cross-Origin Resource Sharing)
条件:
1、请求方式:HEAD、GET、POST
2、请求头信息:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type 对应的值是以下三个中的任意一个
application/x-www-form-urlencoded
multipart/form-data
text/plain
注意:同时满足以上两个条件时,则是简单请求,否则为复杂请求
1 DOCTYPE html>
2 html lang="en">
3 head>
4 meta charset="UTF-8">
5 title>Titletitle>
6 script src="/statics/jquery.js">script>
7 head>
8 body>
9
10 input type="button" onclick="jQueryAjax();" value="jqueryAjax">
11 input type="button" onclick="jQueryAjaxComplecate();" value="jQueryAjaxComplecate" >
12 script>
13 // TODO 简单的CORS请求, 请求的方法为 POST
14 function jQueryAjax() {
15 $.ajax({
16 url: ‘http://yhycn.com:8002/cors‘,
17 type: ‘POST‘,
18 data: {‘k1‘: ‘v1‘},
19 success: function (arg) {
20 console.log(arg)
21 }
22 })
23 }
24
25 // TODO 复杂的cors, 请求的方式不是HEAD、GET、POST中的一种,满足复杂请求的要求, 可以自定义请求头,是否携带cookie
26 function jQueryAjaxComplecate() {
27 $.ajax({
28 url: ‘http://yhycn.com:8002/cors‘,
29 type: ‘PUT‘,
30 // 设置一个请求头,自定义请求头, 自定义了headers也是属于复杂的请求,因此需要在后台允许这样的headers
31 headers: {‘h1‘: ‘hh1‘},
32 // 指定在客户端跨域发送请求的时候,携带cookie
33 xhrFields:{withCredentials: true},
34 data: {‘k1‘: ‘v1‘},
35 success: function (arg) {
36 console.log(arg);
37 }
38 })
39 }
40 script>
41 body>
42 html>
1 # Python write by yhy
2 # Python write by yhy
3 import tornado.web
4 import tornado.ioloop
5
6 class IndexHandler(tornado.web.RequestHandler):
7 def get(self, *args, **kwargs):
8 self.write(‘hello‘)
9
10 class CorsHandler(tornado.web.RequestHandler):
11 def get(self, *args, **kwargs):
12 self.write(‘{"status": 1, "message": "get"}‘)
13
14 def post(self, *args, **kwargs):
15 # 服务端设置一个允许跨域的响应头,响应头的key=‘Access-Control-Allow-Origin‘, value=客户端的域名, * 表示所有的客户端都可以
16 self.set_header(‘Access-Control-Allow-Origin‘, ‘*‘)
17 self.write(‘{"status": 1, "message": "post"}‘)
18
19 # 这个是浏览器自动发送的域检请求
20 def options(self, *args, **kwargs):
21 # 指定允许客户端发送PUT请求
22 self.set_header(‘Access-Control-Allow-Origin‘, ‘http://yhy.com:8001‘)
23 self.set_header(‘Access-Control-Allow-Methods‘, ‘PUT, DELETE‘)
24 # 允许自定义的请求头通过
25 self.set_header(‘Access-Control-Allow-Headers‘, ‘h1, h2‘)
26 self.set_header(‘Access-Control-Allow-Credentials‘, ‘true‘)
27
28 def put(self, *args, **kwargs):
29 # 给客户端设置cookie值,当客户端请求的时候,会携带cookie值,
30 # TODO 应该注意的是,如果客户端跨域请求的时候携带了cookie值的话,那么需要将Access-Control-Allow-Origin的值设置为客户端的域名地址URL
31 print(self.cookies)
32 self.set_cookie(‘k1‘, ‘kkkk‘)
33 self.set_header(‘Access-Control-Allow-Origin‘, ‘http://yhy.com:8001‘)
34 self.set_header(‘Access-Control-Allow-Credentials‘, ‘true‘)
35 self.write(‘put‘)
36
37 settings = {
38 ‘template_path‘: ‘views‘,
39 ‘static_path‘: ‘statics‘,
40 ‘static_url_prefix‘: ‘/statics/‘,
41 }
42
43 application = tornado.web.Application([
44 (r‘/index‘, IndexHandler),
45 (r‘/cors‘, CorsHandler),
46 ], **settings)
47
48 if __name__ == ‘__main__‘:
49 application.listen(8002)
50 tornado.ioloop.IOLoop.instance().start()