同源策略

同源策略(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. vue-cli快速搭建项目的几个文件(一)

    ===========app.vue文件============= <template>   <div id="app">       <router ...

  2. Linux中的info page

    Linux系统中除了使用man来查询命名或者相关文件的用法,还可以使用info命令.与man命令不同的是,info命令将数据拆成一个一个段落,每个段落使用单独的页面编写,同时页面中还有类似超链接的功能 ...

  3. ETSI GS MEC 013,UE 位置 API

    目录 文章目录 目录 版本 功能理解 Relation with OMA APIs Relation with OMA API for Zonal Presence Relation with OMA ...

  4. 用pageOffice控件实现 office word文档在线编辑 表格中写数据的方法

    PageOffice对Word文档中Table的操作,包括给单元格赋值和动态添加行的效果. 1 应用场景 OA办公中,经常要在文档的指定位置表格,填充后端指定数据. 如word文档中,表格数据 如下表 ...

  5. 服务器root密码忘记,使用centos7 紧急模式修改root密码

    一.实战场景 公司一台centos7服务器root密码忘记了,需要你修改root密码,找回root身份. 二.进入紧急模式修改root密码 首先重启服务器,看到这界面时选择第一项,按下e键进行编辑 2 ...

  6. 深入剖析Arthas源码

    一. 前言 Arthas 相信大家已经不陌生了,肯定用过太多次了,平时说到 Arthas 的时候都知道是基于Java Agent的,那么他具体是怎么实现呢,今天就一起来看看. 首先 Arthas 是在 ...

  7. zabbix笔记_001

    zabbix介绍 zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案. zabbix能监视各种网络参数,保证服务器系统的安全运营:并提供灵活的通知机制以让系统管 ...

  8. golang import 导入的四种方式

    1 标准导入: import "package_name" 2 导入别名: import ( alias "package_name" ) 3 匿名导入: _ ...

  9. uniapp 小程序分享功能

    上个月在做小程序的项目时,甲方需要给小程序添加个分享的功能,查看uniapp官方文档后,发现uniapp有自带的小程序分享功能(https://uniapp.dcloud.io/api/plugins ...

  10. uniapp 返回顶部

    <template> <view> <view class="btn" @tap="toTop" :style="{'d ...