跨域,Content-Type组件

1,跨域:是浏览器的同源策略

  • 阻止ajax请求不组织src请求

2,一个源的定义:如果两个页面的协议,端口(如果由指定)和域名都相同,则两个页面具有相同的源

下面给出相对http://a.xyz.com/dir/page.html同源检测的示例

URL结果原因
http://a.xyz.com/dir2/other.html成功 
http://a.xyz.com/dir/inner/another.html成功 
https://a.xyz.com/secure.html失败不同协议(http和https)
http://a.xyz.com:81/dir/etc.html失败不同端口(81和80)
http://z.opq.com/dir/other.html失败不同域名(xyz和opq)

3,同源策略是什么

同源策略是浏览器的一个安全功能,不同源的客户脚本在没有明确授权的情况下,不能读写对方资源,所以xyz.com下的js脚本采用abc.com里面的文件数据是会被拒绝的

同源策略限制了同一个源加载的文档或脚本如何与来自另一个源的资源进行交互,这是一个用于隔离潜在恶意文件的重要机制

4,不受同源策略限制

  1. 页面中的连接,重定向以及表单提交时不会受到同源策略限制的
  2. 跨域资源的引入是可以的,但是js不能读写加载的内容,如嵌入式到页面中<script src=" "></script>, <img>, <link>, <iframe>等

5,CORS跨域请求

CORS即Cross Resource Sharing跨域资源共享

那么跨域请求还分两种,一种是简单请求,一种是复杂请求~~~

5.1>简单请求

HTTP方法是下列方法之一

  • HEAD GET POST

HTTP头信息不超过以下几种字段

  • Accept, Accept-Language, Last-Event-ID
  • Content-Type只能是以下类型中的一个
    • application/x-www-from-urlencoded
    • multipart/form-data
    • text/plain

任何一个不满足上述要求的请求,即会被认为是复杂请求~~

复杂请求会发出一个预请求,我们也叫预检, OPTIONS请求~~

5.2>浏览器的同源策略

  • 跨域是因为浏览器的同源策略导致的,也就是说浏览器会阻止非同源的请求~~
  • 那什么是非永远呢~~即域名不同,端口不同属于非同源的~~~
  • 浏览器只阻止表单以及ajax请求,并不会阻止src请求,所以我们的cnd,图片等src请求都可以发~~

5.3>解决跨域

  • JSONP:jsonp的实现是根据浏览器不阻止请求入手~来实现的~~

 

class Test(APIView):

    def get(self, request):
        callback = request.query_params.get("callback", "")
        ret = callback + "(" + "'success'" + ")"
        return HttpResponse(ret)

 

jsonp的前端ajax代码

<button id="btn_one">点击我向JsonP1发送请求</button>
<script>
    // 测试发送请求失败 跨域不能得到数据
    $('#btn_one').click(function () {
        $.ajax({
            url: "http://127.0.0.1:8000/jsonp1",
            type: "get",
            success: function (response) {
                console.log(response)
            }
        })
    });
    
    function handlerResponse(response) {
        alert(response)
    };
    
    window.onload = function () {
        $("#btn_one").click(function () { let script_ele = document.createElement("script"); script_ele.src = "http://127.0.0.1:8000/jsonp1?callback=handlerResponse"; document.body.insertBefore(script_ele, document.body.firstChild); }) } </script>

jsonp解决跨域只能发送get请求,并且实现起来需要前后端交互比较多

  • 添加响应头
from django.utils.deprecation import MiddlewareMixin


class MyCors(MiddlewareMixin):
    def process_response(self, request, response):
        response["Access-Control-Allow-Origin"] = "*"
        if request.method == "OPTIONS":
            # 复杂请求会先发预检
            response["Access-Control-Allow-Headers"] = "Content-Type"
            response["Access-Control-Allow-Methods"] = "PUT,PATCH,DELETE"
        return response

 6,ContentType组件

  • 需求
  • 现在我们有这样一个需求~我们的商城里有很多的商品~~节目要来了~~我们要搞活动~~
  • 那么我们就要设计优惠券~~优惠券都有什么类型呢~~满减的~折扣的~立减的~~
  • 我们对应着我们活动类型~对我们的某类商品设计优惠券~~比如~~
  • 家电是一类商品~~实物是一类商品~那么我们可以设计家电折扣优惠券~以及实物满减优惠券等
  • 那么表结构怎么设计~~

代码如下:

from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation

# Create your models here.


class Food(models.Model):
    """
    id      name
    1       酱香饼
    2       鸡蛋饼
    3       水煎包
    """
    name = models.CharField(max_length=32) # 反向查询用 coupons = GenericRelation(to="Coupon") class Fruit(models.Model): """ id name 1 红心蜜柚 2 黑美人西瓜 """ name = models.CharField(max_length=32) # 反向查询用 coupons = GenericRelation(to="Coupon") # class Table(models.Model): """ 第一版 id title food_id fruit_id.... 1 酱香饼买一送一 1 null 2 黑美人西瓜2折 null 2 """ # title = models.CharField(max_length=32) # # 第一版设计 # food = models.ForeignKey(to="Food") # fruit = models.ForeignKey(to="Fruit") # # # class MyTable(models.Model): """ id app_name table_name 1 Demo Food 2 Demo Fruit """ # # 第二版设计 # table = models.ForeignKey(to="MyTable") # object_id = models.IntegerField() # app_name = models.CharField(max_length=32) # table_name = models.CharField(max_length=32) class Coupon(models.Model): """ 第三版 id title table_id object_id 1 酱香饼买一送一 1 1 2 黑美人西瓜2折 2 2 """ # 第三版用django自带的ContentType表 title = models.CharField(max_length=32) # content_type和ContentType表外键关联ContentType表是django自带的表 content_type = models.ForeignKey(to=ContentType) object_id = models.IntegerField() # 不会生成字段,只用于关联到对象的 content_object = GenericForeignKey("content_type", "object_id")

遇到这种情况,一张表跟多种表外键关联的时候, Django就提供了ContentType组件~

ContentType是Django的内置的一个应用,可以追踪项目中所有的app和model的对应关系,并记录ContentType表中.

当我们的项目做数据库迁移的后,会有很多自带的表,其中就有django_content_type表.

  • ContentType组件的作用:
    • 在model中定义ForeiginKey字段,并关联到ContentType表,通常这个字段命名为content-type
    • 在model中定义PositiveIntergerField字段,用来存储关联表中的主键,通常我们用object_id
    • 在model中定义GenericForeignKey字段,传入上面两个字段的名字
    • 方便反向查询可以定义GenericRelation字段

视图函数的代码如下:

 

from django.shortcuts import render
from rest_framework.views import APIView
from django.http import HttpResponse
from .models import Food, Fruit, Coupon
from django.contrib.contenttypes.models import ContentType

# Create your views here.


class TestView(APIView): def get(self, request): # 找到表id以及表对象 # content_type_obj = ContentType.objects.filter(app_label="Demo", model="food").first() # print(type(content_type_obj)) # model_class = content_type_obj.model_class() # print(model_class) # print(content_type_obj.id) # 给酱香饼创建优惠券 food_obj = Food.objects.filter(id=1).first() Coupon.objects.create(title="酱香饼买一送小威",content_object=food_obj) # 给黑美人加优惠券 # fruit_obj = Fruit.objects.get(id=2) # Coupon.objects.create(title="黑美人2折", content_type_id=9, object_id=2) # 查询优惠券绑定对象 # coupon_obj = Coupon.objects.filter(id=1).first() # print(coupon_obj.content_object.name) # 查某个对象的优惠券 food_obj = Food.objects.filter(id=1).first() print(food_obj.coupons.all()) return HttpResponse("ok")

 

转载于:https://www.cnblogs.com/ljc-0923/p/10265354.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值