Django-解决跨域请求(基于js,jQuery的josnp,设置响应头的cors)
同源策略
同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。
url http ip port paht ? 数据
if 协议 IP PORT相同,同源
一,问题描述
1 django 创建2个项目
2 项目一,开启一个send_ajax请求 http://127.0.0.1:8000
3 访问正常
4
5 项目二,没有send_ajax请求 http://127.0.0.1:8010
6 那么这时候如果你通过ajax访问的 url:http://127.0.0.1:8000/send_ajax
7 浏览器会报错,内容是已拦截跨域请求,同源策略禁止读取位于http://127.0.0.1:8000/send_ajax远程资源,原因:cors头缺少 ‘Access-Control-Allow-Origin’
1.1 思考
jsonp是json用来跨域的一个东西。原理是通过script标签的跨域特性来绕过同源策略。
1 跨域请求:
2 ajax请求一定会被拦截
3
4 核心任务:跨域请求的是数据,数据,数据
5
6 通过引入jquery cdn 可以跨域 我们想 是不是script标签不会被拦截呢?
7 <script src=" https://cdn.bootcss.com/jquery/3.2.1/jquery.js "></script>
1.2跨域请求的演变
1 项目一 views
2 import json
3 def send_ajax(request):
4 return HttpResponse("yuan") # 第一次返回字符串
5 return HttpResponse("yuan()") # 第二次返回函数字符串
6 return HttpResponse("yuan('yuan')") # 第三次返回函数参数字符串
7 s='hello world'
8 return HttpResponse("yuan('%s')"%s) # 第四次返回函数字符串数据
9
10 s={"name":"egon","age":122}
11 return HttpResponse("%s('%s')"%(func_name,json.dumps(s))) # 第五次返回函数json字符串
12
13 项目二 html
14 第一次字符串,你要是知道数据是什么还请求干什么?所以这里只是个引子,告诉你可以这样做
15 <script>yuan</script>
16 <script src="http://127.0.0.1:8000/send_ajax"></script>
17
18
19 第二次函数字符串
20 <script>function yuan(){alert(123)}</script>
21 <script src="http://127.0.0.1:8000/send_ajax"></script>
22
23
24 第三次返回函数参数字符串
25 <script>function yuan(arg){alert(arg)}</script>
26 <script src="http://127.0.0.1:8000/send_ajax"></script>
27
28
29 第四次返回函数字符串数据(数据也是字符串)
30 <script>function yuan(arg){alert(arg)}</script>
31 <script src="http://127.0.0.1:8000/send_ajax"></script>
32
33
34 第五次返回函数json字符串
35 <script>function yuan(arg){alert(Json.parse(arg))}</script>
36 <script src="http://127.0.0.1:8000/send_ajax"></script>
1.3问题
1 我不能硬生生的将<script src="http://127.0.0.1:8000/send_ajax"></script>写在html里面,我需要动态创建下面的函数
我们通过触发点击事件函数创建
1 <script>
2 function yuan(arg) {
3 console.log(arg);
4 console.log(JSON.parse(arg));
5 }
6 </script>
7
8 <script>
9 $(".send_ajax").click(function () {
10 kuayu_request("http://127.0.0.1:8000/send_ajax/")
11 });
12 function kuayu_request(url) {
13 var $script=$("<script>"); // 创建script标签,是一个jquery对象: <script>
14 $script.attr("src",url);
15 $("body").append($script);
16 $("body script:last").remove();
17 }
18 </script>
1.4 问题
1 1 问题函数名字是不是可以通过请求传送到后端呢?应该是同步的,可否通过回调函数?
可以通过发送请求的时候带着数据,数据包含你的函数名称,这样传到后端,再让后端返回你这个函数和数据,就可以执行了
1 项目二 html
2 <script>
3 $(".send_ajax").click(function () {
4 kuayu_request("http://127.0.0.1:8000/send_ajax/?callback=bar")
5 });
6 function kuayu_request(url) {
7 var $script=$("<script>"); // 创建script标签,是一个jquery对象: <script>
8 $script.attr("src",url);
9 $("body").append($script);
10 $("body script:last").remove();
11 }
12 </script>
13
14
15 项目一 views
16 def send_ajax(request):
17 func_name = request.GET.get('callback')
18 s = 'hello'
19 return HttpResponse("%s('%s')"%(func_name,json.dump(s)))
之前都是引子,下面才是真正的用法。。
ajax的跨域请求写法
1 <script>
2
3 $(".send_ajax").click(function () {
4
5 $.ajax({
6 url:"http://127.0.0.1:8000/send_ajax/",
7 success:function (data) {
8 alert(data)
9 },
10 // 跨域请求 <script> 告诉服务器我要什么类型的数据contenttype是告诉服务器我是什么类型数据
11 dataType:"jsonp",
12 jsonp: 'callbacks', //?callbacks=SayHi 相当于这个,问题就是在于前后端的函数名要相同
13 jsonpCallback:"SayHi"
14 })
15
16
17 });
18
19 function SayHi(arg) {
20 console.log("hello",arg)
21 }
22 </script>
23
24 {#// ==========================================基于jquery的JSONP的实现3 (推荐)#}
25
26 <script>
27
28 $(".send_ajax").click(function () {
29
30 $.ajax({
31 url:"http://127.0.0.1:8000/send_ajax/",
32 dataType:"jsonp", // 跨域请求 <script>
33 // callbacks=? ?就是随机字符串了,后端传回来运行的就是success函数,也就是funciton 函数参数是数据
34 jsonp: 'callbacks',
35 success:function (data) {
36 console.log(data)
37 }
38 })
39
40 });
41
42 </script>
jsonp的所有实现和应用例子
项目一的views.py
1 import json
2 def send_ajax(request):
3 s={"name":"egon","age":122}
4 return HttpResponse("list('%s')"%json.dumps(s))
项目二的index.html
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>Title</title>
6 <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js "></script>
7 </head>
8 <body>
9 <h1>项目2的首页</h1>
10 <button class="send_ajax">send_ajax</button>
11
12
13 {#// ==========================================基于JS的JSONP的实现#}
14 <script>
15 function bar(arg) {
16 console.log(arg);
17 console.log(JSON.parse(arg));
18 }
19 </script>
20
21 <script>
22
23 $(".send_ajax").click(function () {
24 kuayu_request("http://127.0.0.1:8000/send_ajax/?callback=bar") // 回调函数
25 });
26 // 创建script添加scr属性,获取数据
27 function kuayu_request(url) {
28 var $script=$("<script>"); // 创建script标签,是一个jquery对象: <script>
29 $script.attr("src",url);
30 $("body").append($script);
31 $("body script:last").remove();
32 }
33
34 </script>
35
36
37 <hr>
38
39 {#// ==========================================基于jquery的JSONP的实现1#}
40
41
42 <script>
43
44 $(".send_ajax").click(function () {
45 // getJSON帮助我们创建了script标签和src属性 ,还有个参数,data= 可以写入一些给后端的字符串
46 // 匿名函数,函数会有getJSON创建随机字符串也就是callbacks=?的问好的值,函数参数的data是数据
47 $.getJSON("http://127.0.0.1:8000/send_ajax/?callbacks=?",function (data) {
48 console.log(data)
49 })
50 })
51
52 </script>
53
54
55 {#// ==========================================基于jquery的JSONP的实现2#}
56
57 <script>
58
59 $(".send_ajax").click(function () {
60
61 $.ajax({
62 url:"http://127.0.0.1:8000/send_ajax/",
63 success:function (data) {
64 alert(data)
65 },
66 // 跨域请求 <script> 告诉服务器我要什么类型的数据contenttype是告诉服务器我是什么类型数据
67 dataType:"jsonp",
68 jsonp: 'callbacks', //?callbacks=SayHi 相当于这个,问题就是在于前后端的函数名要相同
69 jsonpCallback:"SayHi"
70 })
71
72
73 });
74
75 function SayHi(arg) {
76 console.log("hello",arg)
77 }
78 </script>
79
80 {#// ==========================================基于jquery的JSONP的实现3 (推荐)#}
81
82 <script>
83
84 $(".send_ajax").click(function () {
85
86 $.ajax({
87 url:"http://127.0.0.1:8000/send_ajax/",
88 dataType:"jsonp", // 跨域请求 <script>
89 // callbacks=? ?就是随机字符串了,后端传回来运行的就是success函数,也就是funciton 函数参数是数据
90 jsonp: 'callbacks',
91 success:function (data) {
92 console.log(data)
93 }
94 })
95
96 });
97
98
99 </script>
100
101 {#// =========================================应用#}
102
103
104 <script>
105
106 $(".send_ajax").click(function () {
107
108 $.ajax({
109 url:"http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403",
110 dataType:"jsonp",
111 jsonp:"callback",
112 jsonpCallback:"list"
113 })
114
115
116 });
117
118 function list(shuju) {
119 console.log(shuju.data); // {data: Array(7)}
120 var data=shuju.data; // [{},{},{},......]
121
122 $.each(data,function (i,weekend) {
123 //console.log(weekend); // {week: "周日", list: Array(19)}
124 console.log(weekend.list); // {week: "周日", list: Array(19)}
125 var week= weekend.week;
126 $("body").append("<div>"+week+"</div>");
127
128 $.each(weekend.list,function (i,show) {
129 console.log(show); // {time: "1800", name: "《都市现场》90分钟直播版块", link: "http://www.jxntv.cn/live/jxtv2.shtml"}
130
131 var $a=$("<a>"); // <a></a>
132 $a.html(show.name);
133 $a.attr("href",show.link);
134
135 $("body").append('<p>');
136 $("body").append($a);
137 $("body").append('</p>');
138
139 })
140
141
142 })
143
144 }
145 </script>
146 </body>
147 </html>
注意 JSONP一定是GET请求
CORS跨域资源共享(CORS,Cross-Origin Resource Sharing)
其本质是设置响应头,使得浏览器允许跨域请求。
项目一要访问项目二的视图,项目二的ajax请求代码如下
1 <h1>项目2的首页cors</h1>
2
3 <button class="send_ajax">send_ajax</button>
4
5 <script>
6
7 $(".send_ajax").click(function () {
8
9 $.ajax({
10 // 这里我访问s1的的send_ajax
11 url:"http://127.0.0.1:8000/send_ajax/",
12 type:'GET', // head get post put delete
13 success:function (data) {
14 console.log(data);
15 console.log('11')
16 }
17 })
18
19 })
20 </script>
项目二通过路由找到视图返回数据的代码如下
1 import json
2 def send_ajax(request):
3 # 授权的origin可以用*代替所有,methods可以多个,用逗号分开,简单的放一起,复杂放一起
4 if request.method == "OPTIONS": # 预检
5 response = HttpResponse()
6
7 response["Access-Control-Allow-Origin"] = "http://127.0.0.1:8011"
8 response["Access-Control-Allow-Methods"] = "PUT"
9
10 return response
11
12 elif request.method == "PUT": # 复杂请求,需要通过预检 put delete
13 s = {"name": "egon", "age": 122}
14
15 response = HttpResponse(json.dumps(s))
16 response["Access-Control-Allow-Origin"] = "http://127.0.0.1:8011"
17
18 return response
19
20 elif request.method == 'GET': # 简单强求 head get post
21 s = {"name": "egon", "age": 122}
22
23 response = HttpResponse(json.dumps(s))
24 response["Access-Control-Allow-Origin"] = "http://127.0.0.1:8011"
25
26 return response
流程:
项目二向项目一发送请求,项目一根据请求匹配路由规则,找到视图,视图首先返回给浏览器,如果没有cors就会被浏览器拦截,有了cors设置,浏览器就不会拦截cors设置的请求方式,最终
返回给项目一的数据,上述例子中,复杂请求(put,delete)先走预检,添加put请求,和允许访问的url,返回给浏览器,浏览器得到后在向服务器发送put请求,拿到数据,最后给项目一。
Django-解决跨域请求(基于js,jQuery的josnp,设置响应头的cors)的更多相关文章
- ajax-解决跨域请求(基于js,jQuery的josnp,设置响应头的cors)
同源策略 同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响.可以说Web是构建在同源策略基础之上的 ...
- django解决跨域请求的问题
跨域请求可以用jsonp来解决,不过今天我发现一个很好用的包:django-cors-headers 只需要简单地配置一下就可 被请求方的setting.py中的配置如下: INSTALLED_APP ...
- Python django解决跨域请求的问题
解决方案 1.安装django-cors-headers pip3 install django-cors-headers 2.配置settings.py文件 INSTALLED_APPS = [ . ...
- js中ajax如何解决跨域请求
js中ajax如何解决跨域请求,在讲这个问题之前先解释几个名词 1.跨域请求 所有的浏览器都是同源策略,这个策略能保证页面脚本资源和cookie安全 ,浏览器隔离了来自不同源的请求,防上跨域不安全的操 ...
- Django使用jsonp和cors解决跨域请求问题
1.使用jsonp的方式解决跨域请求的问题 我启动两个django项目,然后使用的端口不一样,在项目1中通过ajax发请求给项目2,然后接受项目2发送过来的数据 先看项目1的ajax的代码 $(&qu ...
- Django之跨域请求
同源策略 首先基于安全的原因,浏览器是存在同源策略这个机制的,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性. 而如果我们要跳过这个策略,也就是说非要跨域请求,那么就需要通过J ...
- 外部调用mvc的api方法时,如何解决跨域请求问题?
首先,创建一个mvc项目(包含webapi),我们模拟一个场景 1)在项目的Controller 创建一个WeiXinApiController public class WeiXinApiContr ...
- Django之跨域请求同源策略
同源策略: 首先基于安全的原因,浏览器是存在同源策略这个机制的,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性. 而如果我们要跳过这个策略,也就是说非要跨域请求,那么就需要通过 ...
- SpringBoot解决跨域请求拦截
前言 同源策略:判断是否是同源的,主要看这三点,协议,ip,端口. 同源策略就是浏览器出于网站安全性的考虑,限制不同源之间的资源相互访问的一种政策. 比如在域名https://www.baidu.co ...
- JSONP方法解决跨域请求
Ajax跨域请求的问题 跨域:跨域名, 一个域名下的文件去请求了和他不一样的域名下的资源文件(注意是请求文件,而不是数据接口),那么就会产生跨域请求,下面来写一个ajax来跨域请求的例子 <!D ...
随机推荐
- RT-Thread 堆区大小设置
一.利用栈区的空间作为堆区 看过我之前的笔记的小伙伴都知道,以前我是通过申请栈区的空间使用的,感兴趣的小伙伴可以看我之前的笔记,RT-Thread移植到stm32. 在board.c文件文件中的代码如 ...
- 简说Python之面向对象
目录 Python对象 对象的内置方法 __init__方法 __str__方法 对象的多态 对象的封装 对象的继承 之前介绍了函数.对象代表了什么.可以称为"一篮子"计划,把数据 ...
- ITIL4服务价值系统(SVS)与莫比乌斯环:无限服务优化的拓扑之旅
莫比乌斯环:单一而无限的象征 莫比乌斯环,这个拓扑学上的奇观,以其独特的一体两面特性,完美地映射了ITIL4服务价值系统的精髓.它象征着无限.统一和连续性,提示我们看待事物时应超越传统二元对立的视角, ...
- C#库dll配置文件App.config数据库连接项connectionStrings
原文地址:https://www.zhaimaojun.top/Note/5464967 网上一大堆的都是在说怎么修改项目文件,试过了不行,因为里面涉及到vs版本和安装目录等问题,不同的设备配置是不同 ...
- 安装assimp失败
使用Cmake和Visual Studio编译assimp成功(包括Debug和Release),并且安装Release版本也成功,但安装debug版本失败,安装输出信息如下: 通过提示找到脚本文件, ...
- 推荐一个好用的.net开发框架
企业应用开发平台(Enterprise Develop Platform),以下简称EDP.EDP是一套集完整组织架构,全面权限体系,以及各类基础功能于一体的基于.net的企业应用开发平台.其最大的特 ...
- pageoffice 6 实现word文件添加水印
在很多场景下,Word文档正式发文之前,或者说形成最终文档之前,常常需要往Word文件中添加水印,并且会根据文件类型或内容的不同,需要添加的水印也不一样. 添加水印是Word软件里的一个简单功能,直接 ...
- 基本定时器TIM6实现精确延时
1.基本定时器的特点 (1).16位自动重装载累加计数器 (2).16位可编程(可实时修改)预分频器,用于对输入的时钟按系数为1-65536之间的任意数值 !!!注意基本定时器只有向上计数模式,不要被 ...
- 开源一站式敏捷测试管理,极简项目管理平台 itest(爱测试) 6.6.2 发布,便捷迫切功能增强
(一)itest 简介及更新说明 itest 开源敏捷测试管理,testOps 践行者,极简的任务管理,测试管理,缺陷管理,测试环境管理,接口测试5合1,又有丰富的统计分析.可按测试包分配测试用例执行 ...
- 2024-06-05:用go语言,给定三个正整数 n、x 和 y, 描述一个城市中由 n 个房屋和 n 条街道连接的情况。 城市中存在一条额外的街道连接房屋 x 和房屋 y。 需要计算对于每个街道数(
2024-06-05:用go语言,给定三个正整数 n.x 和 y, 描述一个城市中由 n 个房屋和 n 条街道连接的情况. 城市中存在一条额外的街道连接房屋 x 和房屋 y. 需要计算对于每个街道数( ...