zoukankan      html  css  js  c++  java
  • 跨域,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")
  • 相关阅读:
    【Java EE 学习 81】【CXF框架】【CXF整合Spring】
    【Java EE 学习 80 下】【调用WebService服务的四种方式】【WebService中的注解】
    【Java EE 学习 80 上】【WebService】
    【Java EE 学习 79 下】【动态SQL】【mybatis和spring的整合】
    【Java EE 学习 79 上】【mybatis 基本使用方法】
    【Java EE 学习 78 下】【数据采集系统第十天】【数据采集系统完成】
    【Java EE 学习 78 中】【数据采集系统第十天】【Spring远程调用】
    【Java EE 学习 78 上】【数据采集系统第十天】【Service使用Spring缓存模块】
    【Java EE 学习 77 下】【数据采集系统第九天】【使用spring实现答案水平分库】【未解决问题:分库查询问题】
    【Java EE 学习 77 上】【数据采集系统第九天】【通过AOP实现日志管理】【通过Spring石英调度动态生成日志表】【日志分表和查询】
  • 原文地址:https://www.cnblogs.com/ljc-0923/p/10265354.html
Copyright © 2011-2022 走看看