• 同源策略和解决


    同源策略

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

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

     例子

    项目一 index.html 端口 8000
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>同源2</title>
    </head>
    <body>
    <h3>主页</h3>
    
    <button class="get_service">点我</button>
    
    <script src="/static/jquery-3.3.1.js"></script>
    <script>
    
            $(".get_service").click(function () {
                $.ajax({
                    url:"http://127.0.0.1:8008/service/",  // 注意 我请求的是另一个服务器
                    success:function (data) {
                        console.log(data);
                    }
    
                })
            });
    </script>

    项目二  view.py  端口 8008

    from django.shortcuts import render,HttpResponse
    
    # Create your views here.
    
    def index(request):
    
        return render(request,'index.html')
    
    import json
    def service(request):
        info = {"name": "yk", "age": 20}
    
        return HttpResponse(json.dumps(info))

    当我点击项目一 里的 button 按钮时,提示如下错误

    已拦截跨源请求:同源策略禁止读取位于 http://127.0.0.1:8008/service/ 的远程资源。(原因:CORS 头缺少 'Access-Control-Allow-Origin')。

    Jsonp

    JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。其核心思想是利用JS标签里面的跨域特性进行跨域数据访问,

    在JS标签里面存在的是一个跨域的URL,实际执行的时候通过这个URL获得一段字符串,这段返回的字符串必须是一个合法的JS调用,通过EVAL这个字符串来完成对获得的数据的处理。

    jsonp是json用来跨域的一个东西。原理是通过script标签的跨域特性来绕过同源策略

    项目一 index.html 端口 8000

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>同源2</title>
    </head>
    <body>
    <h3>主页</h3>
    <button class="get_service">点我</button> <script src="/static/jquery-3.3.1.js"></script> <script> function func(arg) { console.log(arg); console.log(typeof arg); data = JSON.parse(arg); console.log(data); console.log(typeof data); } </script> <script src="http://127.0.0.1:8008/service/"></script>

    项目二  view.py  端口 8008

    from django.shortcuts import render,HttpResponse
    
    # Create your views here.
    
    def index(request):
    
        return render(request,'index.html')
    
    import json
    def service(request):
        info = {"name": "yk", "age": 20}
    
        return HttpResponse("func('%s')" % json.dumps(info))

    当再次刷新index.htnl

    可以见到,成功访问到数据

    项目一 index.html 端口 8000  点击按钮获取数据

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>同源2</title>
    </head>
    <body>
    <h3>主页</h3>
    
    <button class="get_service">点我</button>
    
    <script src="/static/jquery-3.3.1.js"></script>
    <script>
        function func(arg) {
    
            console.log(arg);
            console.log(typeof arg);
    
            data = JSON.parse(arg);
            console.log(data);
            console.log(typeof data);
        }
    
    </script>
    
        $(".get_service").click(function () {#}
    
        $(".get_service").click(function () {
    
            var ele_script = $("<script>");
    
            ele_script.attr("src", "http://127.0.0.1:8008/service/");
            ele_script.attr("id", "jsonp");
            $("body").append(ele_script);
    
            $("#jsonp").remove();}
        )
    
    </script>

    jQuery对JSONP的实现

    项目一 index.html 端口 8000

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>同源2</title>
    </head>
    <body>
    <h3>主页</h3>
    
    <button class="get_service">点我</button>
    
    <script src="/static/jquery-3.3.1.js"></script>
    <script>
    
        $(".get_service").click(function () {
    
            $.ajax({
                url: "http://127.0.0.1:8008/service/",
                type: "get",
                dataType: "jsonp",   //必须有,告诉server,这次访问要的是一个jsonp的结果。
                jsonp: "callbacks",  //jQuery帮助随机生成的:callbacks="jqueryxxxx"
           // jsonpCallback:"SayHi" ,  // 如果指定 ,则回调函数名 为SayHi
                success: function (data) {
                    console.log(data)
                }
            })
    
        })
    
    </script>
    
    </body>
    </html>

    项目二  view.py  端口 8008

    from django.shortcuts import render,HttpResponse
    
    # Create your views here.
    
    def index(request):
    
        return render(request,'index.html')
    
    import json
    
    def service(request):
        func = request.GET.get("callbacks")   # 获取 回调函数名
    
        info = {"name": "yk", "age": 20}
    
        return HttpResponse("%s('%s')" % (func,json.dumps(info)))

      jsonp: 'callbacks'就是定义一个存放回调函数的键,jsonpCallback是前端定义好的回调函数方法名'SayHi',server端接受callback键对应值后就可以在其中填充数据打包返回了; 

      jsonpCallback参数可以不定义,jquery会自动定义一个随机名发过去,那前端就得用回调函数来处理对应数据了。利用jQuery可以很方便的实现JSONP来进行跨域访问。  

    注意 JSONP一定是GET请求

    CORS

    CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

    整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,

    代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

    因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

    支持跨域,简单请求

    服务器设置响应头:Access-Control-Allow-Origin = '域名' 或 '*'

    支持跨域,复杂请求

    由于复杂请求时,首先会发送“预检”请求,如果“预检”成功,则发送真实数据。

    • “预检”请求时,允许请求方式则需服务器设置响应头:Access-Control-Request-Method
    • “预检”请求时,允许请求头则需服务器设置响应头:Access-Control-Request-Headers
    
    
    
    def service(request):
    
        info={"name":"egon","age":34,"price":200}
    
        response=HttpResponse(json.dumps(info))
        response["Access-Control-Allow-Origin"]="http://127.0.0.1:8008"  # 设置响应头:Access-Control-Allow-Origin = '域名' 或 '*'
        #response["Access-Control-Allow-Origin"]="*"
        return  response
     
  • 相关阅读:
    (Java实现) 洛谷 P1106 删数问题
    (Java实现) 洛谷 P1603 斯诺登的密码
    (Java实现) 洛谷 P1036 选数
    (Java实现) 洛谷 P1012 拼数
    (Java实现) 洛谷 P1028 数的计算
    (Java实现) 洛谷 P1553 数字反转(升级版)
    (Java实现) 洛谷 P1051 谁拿了最多奖学金
    (Java实现) 洛谷 P1051 谁拿了最多奖学金
    (Java实现) 洛谷 P1106 删数问题
    目测ZIP的压缩率
  • 原文地址:https://www.cnblogs.com/ykgo/p/9489687.html
Copyright © 2020-2023  润新知