同源策略

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。

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)的更多相关文章

  1. ajax-解决跨域请求(基于js,jQuery的josnp,设置响应头的cors)

    同源策略 同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响.可以说Web是构建在同源策略基础之上的 ...

  2. django解决跨域请求的问题

    跨域请求可以用jsonp来解决,不过今天我发现一个很好用的包:django-cors-headers 只需要简单地配置一下就可 被请求方的setting.py中的配置如下: INSTALLED_APP ...

  3. Python django解决跨域请求的问题

    解决方案 1.安装django-cors-headers pip3 install django-cors-headers 2.配置settings.py文件 INSTALLED_APPS = [ . ...

  4. js中ajax如何解决跨域请求

    js中ajax如何解决跨域请求,在讲这个问题之前先解释几个名词 1.跨域请求 所有的浏览器都是同源策略,这个策略能保证页面脚本资源和cookie安全 ,浏览器隔离了来自不同源的请求,防上跨域不安全的操 ...

  5. Django使用jsonp和cors解决跨域请求问题

    1.使用jsonp的方式解决跨域请求的问题 我启动两个django项目,然后使用的端口不一样,在项目1中通过ajax发请求给项目2,然后接受项目2发送过来的数据 先看项目1的ajax的代码 $(&qu ...

  6. Django之跨域请求

    同源策略 首先基于安全的原因,浏览器是存在同源策略这个机制的,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性. 而如果我们要跳过这个策略,也就是说非要跨域请求,那么就需要通过J ...

  7. 外部调用mvc的api方法时,如何解决跨域请求问题?

    首先,创建一个mvc项目(包含webapi),我们模拟一个场景 1)在项目的Controller 创建一个WeiXinApiController public class WeiXinApiContr ...

  8. Django之跨域请求同源策略

    同源策略: 首先基于安全的原因,浏览器是存在同源策略这个机制的,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性. 而如果我们要跳过这个策略,也就是说非要跨域请求,那么就需要通过 ...

  9. SpringBoot解决跨域请求拦截

    前言 同源策略:判断是否是同源的,主要看这三点,协议,ip,端口. 同源策略就是浏览器出于网站安全性的考虑,限制不同源之间的资源相互访问的一种政策. 比如在域名https://www.baidu.co ...

  10. JSONP方法解决跨域请求

    Ajax跨域请求的问题 跨域:跨域名, 一个域名下的文件去请求了和他不一样的域名下的资源文件(注意是请求文件,而不是数据接口),那么就会产生跨域请求,下面来写一个ajax来跨域请求的例子 <!D ...

随机推荐

  1. CF877F Ann and Books (分类统计贡献+普通莫队)

    CF877F Ann and Books 题意: 商店里有 \(n\) 本书,每本书中有 \(a_i\) 个 \(t_i=1/2\) 类问题. \(m\) 次询问,每次询问给出一个区间,求有多少个符合 ...

  2. 谷歌 hackbar 不能使用的问题

    谷歌 hackbar 不能使用的问题 下载 hackbar 插件:https://github.com/Mr-xn/hackbar2.1.3 解压文件,将其拖入 chrome 扩展程序中 点击详情,点 ...

  3. MacOS安装和使用标注软件“labelImg”教程

    原文发布于:https://blog.zhaoxuan.site/archives/16.html: 第一时间获取最新文章请关注博客个人站:https://blog.zhaoxuan.site. 简介 ...

  4. ruby操作excel

    操作xlsx axlsx插件 操作xls spreadsheet插件

  5. HDU 多校 2023 Round #6 题解

    HDU 多校 2023 Round #6 题解 \(\text{By DaiRuiChen007}\) A. Count Problem Link 题目大意 求有多少个长度为 \(n\),字符集大小为 ...

  6. 防止XSS(跨站脚本攻击)漏洞

    点击查看代码 - 输入验证和过滤:对于用户输入的数据,进行严格的验证和过滤.可以使用正则表达式或其他验证方式,确保输入的数据符合预期的格式和内容.同时,对于特殊字符进行转义处理,防止恶意代码的注入. ...

  7. 用Java 实现一个异步任务 可终止,可中断,可继续功能

    在 Java 中实现一个异步任务可以使用多线程和线程池技术,同时需要考虑终止.中断和继续等功能.下面展示一个简单的示例代码,实现异步任务的终止.中断和继续等功能: import java.util.c ...

  8. JSON返回结果修改null为"";json字段为null时输出空字符串

    简介 (Introduction): 背景 json字符串返回的需要"",但是却是null,怎么处理呢,如下 结构图 1 [ 2 { 3 "1":{ 4 &qu ...

  9. angular 16 路由守卫更新

    在 angular16 中守卫使用方式进行了更新,route 守卫被弃用(取消了CanActivate的使用),新增了功能性守卫(CanActivateFn),支持 inject 注入,官网提供了一个 ...

  10. 🔥 Java Solon v2.7.6 发布

    Java Solon 是什么框架? Java "新的"应用开发框架.开放原子开源基金会,孵化项目.从零开始构建(非 java-ee 架构),有灵活的接口规范与开放生态. 追求: 更 ...