cors 跨域请求处理方法

 

  1 day114
  2 
  3 内容回顾:
  4     1. 谈谈你对rest api 的认识。
  5         原来web应用程序时,根据URL不同定位到不同视图函数处理。
  6         rest是一种规范:面向资源
  7             http://api.luffycity.com/v1/users
  8             - 协议:
  9                 http
 10                 https
 11             - 域名
 12                 api.luffycity.com 
 13                 www.luffycity.com/api
 14             - 版本
 15                 
 16             - url中是名词
 17             - method不同执行不同函数:get/post/delete/put/patch
 18             - 返回状态码:200/301/302/404/403/500
 19             - 错误信息:
 20                 {
 21                    msg: '用户名或密码错误'
 22                 }
 23                 def index(request):
 24                     ret = {'code':1000,'data':None}
 25 
 26                     return HttpResponse('xxx',status=200)
 27             - 返回值:
 28                 http://api.luffycity.com/v1/users
 29                 http://api.luffycity.com/v1/users/1
 30                 
 31             - 条件
 32                 http://api.luffycity.com/v1/users?page=1&size=10
 33                 
 34                 PS: 主键ID体现在URL上
 35             - hyperlink
 36                 {
 37                     id: '老司机',
 38                     age: 18,
 39                     group: http://www.luffycti.com/api/v1/group/1/
 40                 }
 41     2. django rest framework
 42         - 10个组件
 43         - 认证/权限/节流/序列化
 44         - 知识:
 45             - 封装,认证。
 46             - 配置,中间件配置;
 47         - 问题:发送邮件、短信、微信提醒
 48         
 49     3. 版本:
 50         - http://www.luffycity.com/api/v1/users 
 51         - http://www.luffycity.com/api/v2/users 
 52 今日内容:
 53     1. ContentType
 54     2. CORS
 55     3. Git
 56     
 57 内容详细:
 58     1. ContentType
 59         背景:学位课、专题课、价格策略
 60         问题1:设计表结构。
 61                 from django.db import models
 62                 from django.contrib.contenttypes.models import ContentType
 63                 from django.contrib.contenttypes.fields import GenericForeignKey,GenericRelation
 64 
 65 
 66                 class DegreeCourse(models.Model):
 67                     name = models.CharField(max_length=32)
 68 
 69                 class Course(models.Model):
 70                     name = models.CharField(max_length=32)
 71 
 72                     # 数据库不生成,只用于链表查询
 73                     policy_list = GenericRelation("PricePolicy")
 74 
 75                 class PricePolicy(models.Model):
 76                     content_type = models.ForeignKey(ContentType)
 77                     object_id = models.PositiveIntegerField()
 78 
 79                     # 不在数据库中生成,只用于帮助你做数据操作
 80                     content_object = GenericForeignKey('content_type', 'object_id')
 81 
 82                     period = models.CharField(max_length=32)
 83                     price = models.FloatField()
 84                     
 85                     
 86         问题2:为专题课1添加3个价格策略
 87                 # course_obj内部包含:id=1,表名称=course
 88                 course_obj = models.Course.objects.get(id=1)
 89                 models.PricePolicy.objects.create(period='10', price=9.9, content_object=course_obj)
 90                 models.PricePolicy.objects.create(period='20', price=19.9, content_object=course_obj)
 91                 models.PricePolicy.objects.create(period='30', price=29.9, content_object=course_obj)
 92                 # course_obj内部包含:id=2,表名称=course
 93                 # course_obj = models.Course.objects.get(id=2)
 94                 # models.PricePolicy.objects.create(period='110', price=9.9, content_object=course_obj)
 95                 # models.PricePolicy.objects.create(period='120', price=19.9, content_object=course_obj)
 96                 # models.PricePolicy.objects.create(period='130', price=29.9, content_object=course_obj)
 97 
 98 
 99                 # degree_course_obj = models.DegreeCourse.objects.get(id=1)
100                 # models.PricePolicy.objects.create(period='8', price=9.9, content_object=degree_course_obj)
101                 # models.PricePolicy.objects.create(period='16', price=19.9, content_object=degree_course_obj)
102                 # models.PricePolicy.objects.create(period='99', price=29.9, content_object=degree_course_obj)
103 
104         问题3:显示所有的价格策略,并将其对应的课程名称显示。
105                 
106                 # policy_list = models.PricePolicy.objects.all()
107                 # for obj in policy_list:
108                 #     print(obj.period,obj.price,obj.content_object,obj.content_object.id,obj.content_object.name)
109 
110             
111         问题4:给你课程ID,获取课程信息+该课程的所有价格策略
112                 course_obj = models.Course.objects.get(id=2)
113                 print(course_obj.id)
114                 print(course_obj.name)
115                 policy_list = course_obj.policy_list.all()
116                 for item in policy_list:
117                     print(item.price,item.period)
118                 
119     
120     2. cors
121         目标:由api解决跨域,本质添加响应头。
122         
123         a. 基本跨域
124             api:
125                 def service(request):
126                     v1 = request.GET.get('v1')
127                     v2 = request.GET.get('v2')
128                     result = v1 + v2
129                     obj =  HttpResponse(result)
130                     # obj['Access-Control-Allow-Origin'] = 'http://localhost:63342,http://localhost:63343,'
131                     obj['Access-Control-Allow-Origin'] = '*'
132                     return obj
133             
134             ajax:
135                 function getData() {
136                     $.ajax({
137                         url:'http://127.0.0.1:8000/service/?v1=横哥&v2=哼',
138                         type:'GET',
139                         success:function (arg) {
140                             alert(arg);
141                         }
142                     })
143                 }
144         
145         b. 自定义请求头:先预检允许头,再发起数据相关请求。
146             api:
147                 
148                 def service(request):
149                     if request.method == 'OPTIONS':
150                         print('进行预检')
151                         obj = HttpResponse()
152                         obj['Access-Control-Allow-Headers'] = 'k1'
153                         obj['Access-Control-Allow-Origin'] = '*'
154                         return obj
155                     else:
156                         v1 = request.GET.get('v1')
157                         v2 = request.GET.get('v2')
158                         result = v1 + v2
159                         obj =  HttpResponse(result)
160                         # obj['Access-Control-Allow-Origin'] = 'http://localhost:63342,http://localhost:63343,'
161                         obj['Access-Control-Allow-Origin'] = '*'
162                         return obj
163     
164             ajax:
165                 function getData() {
166                     $.ajax({
167                         url:'http://127.0.0.1:8000/service/?v1=横哥&v2=哼',
168                         type:'GET',
169                         headers:{
170                             k1:'v1'
171                         },
172                         success:function (arg) {
173                             alert(arg);
174                         }
175                     })
176                 }
177     
178         
179         c. 不寻常的方法:先预检允许方法,再发起数据相关请求。
180             api:
181                 def service(request):
182                     if request.method == 'OPTIONS':
183                         obj = HttpResponse()
184                         obj['Access-Control-Allow-Origin'] = '*'
185                         obj['Access-Control-Allow-Methods'] = 'PUT'
186                         return obj
187                     else:
188                         v1 = request.GET.get('v1')
189                         v2 = request.GET.get('v2')
190                         result = v1 + v2
191                         obj =  HttpResponse(result)
192                         # obj['Access-Control-Allow-Origin'] = 'http://localhost:63342,http://localhost:63343,'
193                         obj['Access-Control-Allow-Origin'] = '*'
194                         return obj
195             ajax:
196                 function getData() {
197                     $.ajax({
198                         url:'http://127.0.0.1:8000/service/?v1=横哥&v2=哼',
199                         type:'PUT',
200                         success:function (arg) {
201                             alert(arg);
202                         }
203                     })
204                 }
205     
206     
207         简单请求和复杂请求:
208             1、请求方式:HEAD、GET、POST
209             2、请求头信息:
210                 Accept
211                 Accept-Language
212                 Content-Language
213                 Last-Event-ID
214                 Content-Type 对应的值是以下三个中的任意一个
215                                         application/x-www-form-urlencoded
216                                         multipart/form-data
217                                         text/plain
218          
219             注意:同时满足以上两个条件时,则是简单请求,否则为复杂请求
220     
221         应用:在django中间件中实现cors做跨域
222             
223     
224     3. git
225         软件,帮助我们做版本控制。
226         a. 安装:https://git-scm.com/downloads
227         b. 基本使用:
228             - 进入你想要管理的文件夹
229             - git init 
230             - git status 
231             - git add . 
232             - git commit -m '一定好好写'
233             
234             - git log 
235             - git reset --hard 23xdfu0lksdfousmner9xf
236             - git reflog 
237             - git reset --hard 23xdfu0lksdfousmner9xf
238     
239     
240             http://www.cnblogs.com/wupeiqi/p/7295372.html
241     
242     
243     
244     
245     
246     
247     
248     
249     
250     
251     
252     
253     
254     
255     
256     
老师笔记

 

我们的跨域请求处理方法有两种,一个是使用jsonp,还有就是用我们的cors

 

先说jsonp,它是利用我们的script标签的的src属性(我们的浏览器允许script标签跨域,这是硬性规定,浏览器就是会支持它跨域,这是没有道理的,我就利用它的这个属性,来实现我们的跨域请求)

它会自动给我们生成一个script标签,然后返回值是一个字符串里面的函数方法,

我们的跨域请求在前端的js代码里面执行,我们的script生成的标签里面有一个src属性,它就是我们的跨域请求地址,

 1 <!DOCTYPE html>
 2 <html>
 3 <head lang="en">
 4     <meta charset="UTF-8">
 5     <title></title>
 6 </head>
 7 <body>
 8 
 9     <p>
10         <input type="button" onclick="Jsonp1();"  value='提交'/>
11     </p>
12 
13     <p>
14         <input type="button" onclick="Jsonp2();" value='提交'/>
15     </p>
16 
17     <script type="text/javascript" src="jquery-1.12.4.js"></script>
18     <script>
19         function Jsonp1(){
20             var tag = document.createElement('script');
21             tag.src = "http://c2.com:8000/test/";
22             document.head.appendChild(tag);
23             document.head.removeChild(tag);
24 
25         }
26 
27         function Jsonp2(){
28             $.ajax({
29                 url: "http://c2.com:8000/test/",
30                 type: 'GET',
31                 dataType: 'JSONP',
32                 success: function(data, statusText, xmlHttpRequest){
33                     console.log(data);
34                 }
35             })
36         }
37 
38 
39     </script>
40 </body>
41 </html>
42 
43 基于JSONP实现跨域Ajax - Demo
ajax利用jsonp实现跨域demo

 

 

上图里面的callback(钱包)这里的call就是我们的后端传过来的数据,就是response里面的字符串所包裹着的字符串,这个callback是一个方法,它以文本格式放到我们的script标签里面是语法所不支持的,会报错,所以我们在script里面要定一个函数,这个函数是callback,里面需要形参,然后我们系统内部就会把这个字符串文本信息给依附到这个script里面的函数上,然后把这个文本信息给抹掉,这样我们的程序就能够正常运行了,这一套流程逻辑就是我们的jsonp内部的实现机制,我们的jsonp需要在script标签里面有一个内置函数function,它是来接收我们的后端传过来字符串里面所包含的函数方法.

 

 

再来说我们的cors对于跨域请求的处理,(用于后端处理)

它主要的逻辑就是添加相应头,

随着技术的发展,现在的浏览器可以支持主动设置从而允许跨域请求,也就是跨域资源共享(Corss-Origin Resource Sharing),本质就是设置相应投,使得浏览器允许跨域请求

 

cors的请求头分为简单请求和复杂请求,

简单请求原则:

1,请求方式:POST,GET两种,

2,请求头信息:

Accept

Accept-Language

Content-Language

Last-Event-ID

Content-Type对应的值是以下三个中的任意一个:

    application/x-www-form-urlencoded

    multipart/form-data

    text/plain

同时满足以上两个条件,就是简单请求,否则就是复杂请求

 

我们的简单请求就是一次请求,

复杂请求就是两次请求,在发送数据之前会做"预检",这个预检就是OPTIONS请求,预检通过才会发送一次请求用于数据传输,

 

如果加上了请求头信息,或者请求类型也就是method除了post/get之外都属于复杂请求

加上请求头就需要在后端把Access-Control-Request-Headers=[]  括号里面就是我们的请求头信息

除了post/get请求之外的请求都是复杂请求,我们在处理的时候就需要在后端把Access-Control-Request-Method=[]  括号里面是method方法

 

 1     a. 基本跨域
 2             api:
 3                 def service(request):
 4                     v1 = request.GET.get('v1')
 5                     v2 = request.GET.get('v2')
 6                     result = v1 + v2
 7                     obj =  HttpResponse(result)
 8                     # obj['Access-Control-Allow-Origin'] = 'http://localhost:63342,http://localhost:63343,'
 9                     obj['Access-Control-Allow-Origin'] = '*'
10                     return obj
11             
12             ajax:
13                 function getData() {
14                     $.ajax({
15                         url:'http://127.0.0.1:8000/service/?v1=横哥&v2=哼',
16                         type:'GET',
17                         success:function (arg) {
18                             alert(arg);
19                         }
20                     })
21                 }
22         
23         b. 自定义请求头:先预检允许头,再发起数据相关请求。
24             api:
25                 
26                 def service(request):
27                     if request.method == 'OPTIONS':
28                         print('进行预检')
29                         obj = HttpResponse()
30                         obj['Access-Control-Allow-Headers'] = 'k1'
31                         obj['Access-Control-Allow-Origin'] = '*'
32                         return obj
33                     else:
34                         v1 = request.GET.get('v1')
35                         v2 = request.GET.get('v2')
36                         result = v1 + v2
37                         obj =  HttpResponse(result)
38                         # obj['Access-Control-Allow-Origin'] = 'http://localhost:63342,http://localhost:63343,'
39                         obj['Access-Control-Allow-Origin'] = '*'
40                         return obj
41     
42             ajax:
43                 function getData() {
44                     $.ajax({
45                         url:'http://127.0.0.1:8000/service/?v1=横哥&v2=哼',
46                         type:'GET',
47                         headers:{
48                             k1:'v1'
49                         },
50                         success:function (arg) {
51                             alert(arg);
52                         }
53                     })
54                 }
55     
56         
57         c. 不寻常的方法:先预检允许方法,再发起数据相关请求。
58             api:
59                 def service(request):
60                     if request.method == 'OPTIONS':
61                         obj = HttpResponse()
62                         obj['Access-Control-Allow-Origin'] = '*'
63                         obj['Access-Control-Allow-Methods'] = 'PUT'
64                         return obj
65                     else:
66                         v1 = request.GET.get('v1')
67                         v2 = request.GET.get('v2')
68                         result = v1 + v2
69                         obj =  HttpResponse(result)
70                         # obj['Access-Control-Allow-Origin'] = 'http://localhost:63342,http://localhost:63343,'
71                         obj['Access-Control-Allow-Origin'] = '*'
72                         return obj
73             ajax:
74                 function getData() {
75                     $.ajax({
76                         url:'http://127.0.0.1:8000/service/?v1=横哥&v2=哼',
77                         type:'PUT',
78                         success:function (arg) {
79                             alert(arg);
80                         }
81                     })
82                 }
几种cors请求方式

 

posted @ 2018-04-24 17:35  dream-子皿  阅读(610)  评论(0)    收藏  举报