zoukankan      html  css  js  c++  java
  • 同源策略和解决

    同源策略

    同源策略(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
     
  • 相关阅读:
    readonly const
    多线程的安全性
    【C++】operator运算符重载
    C++ 多态的实现及原理(转载)
    C语言宽字符处理函数对照表
    UTF8编码规则(转)
    PE文件结构(转)
    C语言中宏定义
    汇编语言移位指令
    数组指针应该结合二维数组多维数组来理解
  • 原文地址:https://www.cnblogs.com/ykgo/p/9489687.html
Copyright © 2011-2022 走看看