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

上图里面的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 }

浙公网安备 33010602011771号