• 何谓同源策略与Jsonp


    同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

    同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。

    1、先来说说什么是源


    • 源(origin)就是指的协议、域名和端口号。
    以上url中的源就是:http://www.company.com:80
    若地址里面的协议、域名和端口号均相同则属于同源。
    以下是相对于 http://www.a.com/test/index.html 的同源检测
    • http://www.a.com/dir/page.html ----成功
    • http://www.child.a.com/test/index.html ----失败,域名不同
    • https://www.a.com/test/index.html ----失败,协议不同
    • http://www.a.com:8080/test/index.html ----失败,端口号不同

    2.什么是同源策略?


    同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。所以a.com下的js脚本采用ajax读取b.com里面的文件数据是会报错的。

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

    二、跨域  


    1、什么是跨域


    受前面所讲的浏览器同源策略的影响,不是同源的脚本不能操作其他源下面的对象。想要操作另一个源下的对象是就需要跨域。

    2、跨域的实现形式


    • 降域 document.domain
    同源策略认为域和子域属于不同的域,如:
    child1.a.com 与 a.com,
    child1.a.com 与 child2.a.com,
    xxx.child1.a.com 与 child1.a.com
    两两不同源,可以通过设置 document.damain='a.com',浏览器就会认为它们都是同一个源。想要实现以上任意两个页面之间的通信,两个页面必须都设置documen.damain='a.com'。
    此方式的特点:
    1. 只能在父域名与子域名之间使用,且将 xxx.child1.a.com域名设置为a.com后,不能再设置成child1.a.com。
    2. 存在安全性问题,当一个站点被攻击后,另一个站点会引起安全漏洞。
    3. 这种方法只适用于 Cookie 和 iframe 窗口。
    • JSONP跨域
    JSONP和JSON并没有什么关系!
    JSONP的原理:(举例: http://127.0.0.1:8001/想得到 http://127.0.0.1:8002/中的数据)在a.com的jsonp.html里创建一个回调函数xxx,动态添加<script>元素,向服务器发送请求,请求地址后面加上查询字符串,通过callback参数指定回调函数的名字。请求地址为 http://127.0.0.1:8001?callback=xxx。在main.js中调用这个回调函数xxx,并且以JSON数据形式作为参数传递,完成回调。

    现在我们看看 http://127.0.0.1:8001/的html代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>首页</title>
    </head>
    <body>
    <p>这是首页!</p>
    <button>提交</button>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script>
        $("button").click(function () {
            alert(123)
            $.ajax({
                url: "http://127.0.0.1:8002//test/",
                success: function (data) {
                    console.log(data)
                }
            })
        })
    </script>
    </body>
    </html>

    在这个代码里面调用了8002的资源。

    8802:的views代码:

    from django.shortcuts import render, HttpResponse
    
    # Create your views here.
    
    
    def test(request):
        print("会出现吗。很是期待哦")
    
        return HttpResponse("this is test")

    这是一个简单的调用。你会发现。浏览器不允许你进行调用。

    因为控制台已经给你调用了

    说明是浏览器不允许你进行跨域.

    但是你们发现没有。同样是跨域调用。我进行jquery的cdn调用就不会进行拦截。

    看到这里你的心里难道就没有点想法吗?

    没有,既然不给我进行js的跨域,那我跨域伪装成上面的那种方式进行调用呀!说干就干,撸起手就是干。

    8001的HTML代码如图:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>首页</title>
    </head>
    <body>
    <p>这是首页!</p>
    {#{% csrf_token %}#}
    <button>提交</button>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script>
    $("button").click(function () {
    
            var html_script = $("<script>");
            html_script.attr("src","http://127.0.0.1:8002/test/");
            html_script.attr("id","test");
            $("body").append(html_script);
            $("#test").remove();//生成的标签调用完毕,马上移除掉。
    })
        function get_data(test2_data) {
            console.log(test2_data)
        }
    </script>
    </body>
    </html>

    8002 的views代码:

    from django.shortcuts import render, HttpResponse
    
    # Create your views here.
    
    
    def test(request):
        print("会出现吗。很是期待哦")
        return HttpResponse("get_data('ok')")  # 传递一个跟8001同名的get_data()函数

    这样调用跨域的资源就不会出错了。

    。现在为了更加灵活,现在将在客户端定义的回调函数传送给服务端。服务端就会返回逸直接定义的回调函数名的方法。将获取的json数据传入这个方法就可以完成回调了。

    8001代码也就是客户端代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>首页</title>
    </head>
    <body>
    <p>这是首页!</p>
    {#{% csrf_token %}#}
    <button>提交</button>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script>
    $("button").click(function () {
    
            var html_script = $("<script>");
            html_script.attr("src","http://127.0.0.1:8002/test/?callbacks=get_data");
            html_script.attr("id","test");
            $("body").append(html_script);
            $("#test").remove();//生成的标签调用完毕,马上移除掉。
    })
        function get_data(test2_data) {
            console.log(test2_data)
        }
    </script>
    </body>
    </html>

    8002也就是服务端只需这样调用即可:

    from django.shortcuts import render, HttpResponse
    import json
    
    # Create your views here.
    
    
    def test(request):
        print("会出现吗。很是期待哦")
        func = request.GET.get("callbacks")
        print(func)
        a_dict = {"key": "values"}
        return HttpResponse("%s(%s)" % (func, json.dumps(a_dict)))  # 需要把数据进行序列化方可以传递过去
    

    让我们来看看结果呗

    这就跨域调用数据成功了。

    jQuery中的Jsonp方法

    只需要改动8001中的html代码即可:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>首页</title>
    </head>
    <body>
    <p>这是首页!</p>
    {#{% csrf_token %}#}
    <button>提交</button>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script>
    $("button").click(function () {
        f("http://127.0.0.1:8002/test/")
    })
     function f(url) {
         $.ajax({
             url: url,
             dataType:"jsonp",
             jsonp: 'callbacks', //这里的值(callbacks)相当于url中的建的名字
             jsonpCallback: 'ok', // 这里的值(ok)相当于回调函数的函数名,也就是url中的值
             success:function (data) {
                 console.log(data)
             }
         });
     }
    </script>
    </body>
    </html>

    你可以正常的跨域调用。

    但是上面的代码有个可以不用有:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>首页</title>
    </head>
    <body>
    <p>这是首页!</p>
    {#{% csrf_token %}#}
    <button>提交</button>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script>
    $("button").click(function () {
        f("http://127.0.0.1:8002/test/")
    })
     function f(url) {
         $.ajax({
             url: url,
             dataType:"jsonp",
             jsonp: 'callbacks', //这里的值(callbacks)相当于url中的建的名字
             //jsonpCallback: 'ok', // 这里的值(ok)相当于回调函数的函数名,也就是url中的值
             success:function (data) {
                 console.log(data)
             }
         });
     }
    </script>
    </body>
    </html>

    从这里可以看出不一定需要自己定义回调函数名也可以,jsonp也可以帮你生成函数名:

    通过CORS实现跨域调用。

    从csdn搬家过来的可能没有图片,原地址https://blog.csdn.net/weixin_38091140
  • 相关阅读:
    使用fiddler进行app弱网测试
    弱网测试
    Java虚拟机的内存模型
    Junit使用
    python安装numpy和scipy的资源
    HTTP资源合集
    http之post方法 提交数据的四种方法
    计算机编码中的换行 CR与LF
    python Mixin 是个啥?
    python mock的简单使用
  • 原文地址:https://www.cnblogs.com/Apy-0816/p/11100262.html
Copyright © 2020-2023  润新知