[oldboy-django][2深入django]浏览器同源策略 + JSONP + cros

浏览器的同源策略:
    - 同源: 同方法,同域名,同端口
             http://www.baidu.com:8000
             http:          方法
             www.baidu.com: 域名
             8000:          端口
    - 定义
        网上解析非常好的一篇
        http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html
    - 限制 ajax只能发给同源的网址;
           限制原理:
                浏览器request--->跨域服务器
                浏览器阻止接收<----跨域服务器响应, 服务器已经做出响应了,而且返回了,只是浏览器阻止接收

    - 解决策略JSONP
        它的基本思想是,网页通过添加一个<script>元素,请跨域请求放在src属性上
        向服务器请求JSON数据
            (注意数据是json,数据是通过回调函数的参数传递回来的,
            所以参数必须是经过json话
            )
        这种做法不受同源政策限制;
        服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。

    JSONP需求:向其他网站发送http请求
        - 解决办法:浏览器直接发送请求(到访问其他网站)--考虑浏览器同源
            - 要求:
                1. 客户端
                    - jsonp发送url, 把funname放到url中 url?callback=myfun
                    - 定义myfun函数 function myfun(arg)

                2. 服务端
                    - 获取callback,  fun_name = request.GET.get(‘callback‘)
                    - arg是请求,需要获取的数据,这个数据必须字符串或者是Json字符串
                    - 字符串 temp = ‘%s(%s)‘ %(fun_name, arg)
                        注意,如果arg是列表等类型要先arg = json.dumps(arg)
                    - 返回字符串
                        return HttpResponse(temp)

                ps: 不是特别必要
                    修改django settings.py里面的ALLOWED_HOSTS = [‘http://www.s4.com‘]

                    修改C:\Windows\System32\Drivers\etc\hosts里面的内容增加内容
                        127.0.0.1   www.s4.com
                        127.0.0.1   www.s5.com

            - 原理:
                只要页面加载下面语句
                <script src="http://www.s4.com:8001/user"></script>
                内存中就会返回http://www.s4.com:8001/user页面内容,
                并且将内容保存在内存中, 在页面的时候,会将内容当做Js渲染

                当请求http://www.s4.com:8001/user?myfun=callback,
                后台返回Json.dumps(‘myfun(arg)‘),
                存储在浏览器内存中,就相当于调用函数 myfun(arg),
                因此,需要在前端定义callback(arg),这样就不需要考虑什么时候调用函数,

                为了节省空间,一般绑定一个事件动态生成script标签,
                    function xxx(){
                        var tag = document.createElement(‘script‘)
                        tag.src = ‘http://www.s4.com:8001/user?callback=myfun‘;
                        document.getElementByTag(‘head‘).appendChild(tag);
                    }

                    function myfun(arg){
                        console.log(arg);
                    }

# JSONP实例--动态创建script标签
    # A网站前端
        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>Title</title>
        </head>
        <body>

        <input type="button" value="jsonp" onclick="test_jsonp();">

        <script>
            function test_jsonp(){
                var tag = document.createElement(‘script‘);
                tag.src = ‘http://127.0.0.1:8001/users?callback=get_users‘;
                document.head.appendChild(tag);
            }

            function get_users(arg){
                alert(123);
                console.log(arg)
            }
        </script>
        </body>
        </html>

    # B网站处理请求
        url(r‘^users‘, views.users),
        def users(request):
            fun_name = request.GET.get(‘callback‘)
            user_list = json.dumps([‘alex‘, ‘egon‘, ‘eric‘])
            temp = "%s(%s)" % (fun_name, user_list)
            return HttpResponse(temp)

# 用jQuery 封装JSONP,
    # 主要是前端不同,其他的一一致
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <input type="button" value="获取用户列表" onclick="getUsers();">
    </body>
    <script src="/static/js/jquery-1.12.4.js"></script>
    <script>
        function getUsers(){
            $.ajax({
                url: ‘http://127.0.0.1:8001/users‘,
                type: ‘GET‘,
                dataType: ‘jsonp‘,
                jsonp: ‘callback‘,      // 指定url传递参数名称
                jsonpCallback: ‘myFun‘ // 指定回调函数
            })
            // jsonp: ‘callback‘, jsonCallback" :‘myFun‘
            // 等效于将?callback=myFun加到url上
        }

        function myFun(arg){
            console.log(arg);
        }
    </script>
    </html>

# jQuery实现跨越的另一种方式$.getJSON()
    利用getJSON来实现,只要在地址中加上callback=?参数即可
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <input type="button" value="获取用户列表" onclick="getUsers();">
    </body>
    <script src="/static/js/jquery-1.12.4.js"></script>
    <script>
        function getUsers(){
            $.getJSON("http://127.0.0.1:8001/users?callback=?", myFun);
        }

        function myFun(arg){
            console.log(arg);
        }

    </script>
    </html>

# 使用jsonp注意:
    - 只能发get请求(生成script标签,里面的src肯定是get请求)
    - 客户端和服务端做好约定
    - jsonp是一项技术,方法;目的是解决跨域问题

# 解决跨域请求的另一种方式:cors : cross site
    在响应增加一个响应头:Access-Control-Allow-Origin, 这样就允许ajax跨域发送请求.
    浏览器看到这个消息头,就不会阻止接收跨域返回的响应
    # 视图函数
        obj = HttpResponse()
        obj[‘Access-Control-Allow-Origin ‘]= ‘*‘
        # 或者obj[‘Access-Control-Allow-Origin ‘]= ‘www.s4.com:8000‘
        return obj

# cros解决浏览器阻止ajax跨域问题 --简单请求
    - 实例
        # 前端
            <body>
            <input type="button" value="cros支持ajax跨域发送请求" onclick="JsAjaxSend();">
            </body>
            <script src="/static/js/jquery-1.12.4.js"></script>
            <script>
                function JsAjaxSend() {
                    $.ajax({
                        url: ‘http://127.0.0.1:8001/new_users‘,
                        type: ‘GET‘,
                        success:function(arg){
                         console.log(arg)
                        }
                    })
                }
            </script>

        # http://127.0.0.1:8001/new_users视图函数
            def new_users(request):
                print(‘请求来了‘)
                user_list = [‘alex‘, ‘egon‘, ‘eric‘]
                user_list_str = json.dumps(user_list)
                obj = HttpResponse(user_list_str)
                obj[‘Access-Control-Allow-Origin‘] = "http://127.0.0.1:8000"
                return obj

# cros解决ajax跨域请求问题--复杂请求
    复杂请求实际上发送了两个请求: OPTIONS,以及后面的复杂请求。
    # 前端
        function JsAjaxSend() {

        $.ajax({
            url: ‘http://127.0.0.1:8001/complicated_users‘,
            type: ‘DELETE‘,
            success:function(arg){
             console.log(arg)
            }
        })
    }

    # 视图 --这里取消了csrf
        def complicated_users(request):
            if request.method == ‘OPTIONS‘:
                # 设置允许delete方法和浏览器接收跨域响应
                obj = HttpResponse()
                obj[‘Access-Control-Allow-Methods‘] = ‘DELETE‘
                obj[‘Access-Control-Allow-Origin‘] = "http://127.0.0.1:8000"
                return obj
            else:
                user_list_str = json.dumps([‘eric‘, ‘alex‘])
                obj = HttpResponse(user_list_str)
                obj[‘Access-Control-Allow-Origin‘] = "http://127.0.0.1:8000"
                return obj

# 如何区分复杂请求和简单请求
    1、请求方式:HEAD、GET、POST
    2、请求头信息:
        Accept
        Accept-Language
        Content-Language
        Last-Event-ID
        Content-Type 对应的值是以下三个中的任意一个
                                application/x-www-form-urlencoded
                                multipart/form-data
                                text/plain
    注意:同时满足以上两个条件时,则是简单请求,否则为复杂请求

# 参考博客
http://www.cnblogs.com/wupeiqi/articles/5703697.html

时间: 2024-10-13 07:26:17

[oldboy-django][2深入django]浏览器同源策略 + JSONP + cros的相关文章

Django之跨域请求同源策略

同源策略: 首先基于安全的原因,浏览器是存在同源策略这个机制的,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性. 而如果我们要跳过这个策略,也就是说非要跨域请求,那么就需要通过JSONP或者CORS来实现了. 一个源的定义 如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源. 举个例子: 下表给出了相对http://a.xyz.com/dir/page.html同源检测的示例: URL 结果 原因 http://a.xyz.com/dir2/oth

浏览器同源策略与跨域出现原因

什么是同源策略? 同源策略(Same origin policy)是一种约定,它是浏览器最核心的也是最基本的安全功能,web也是构建在同源策略基础上,浏览器只是针对同源策略的一种实现. 它是由Netscape提出的一个著名的安全策略,目前支持JavaScript的浏览器都会使用找个策略. 什么是同源? 同源:域名/端口/协议相同 同源分为两种情况:1.dom的同源策略:禁止对不同页面的dom进行操作 2.XMLHttpRequest同源:禁止使用XHR对象向不同源的ip发起http请求 为什么会

浏览器同源策略深入

浏览器对于同源的认定是:协议.域名.端口号必须精确匹配,一模一样 个人总结同源策略的一个首要宗旨是: 阻止能向外传输信息的模块(如javascript)获取到来自不同源的资源,不能获取也就从源头阻止了资源和其中信息的泄露. 很重要的一点是,同源策略阻止的是跨域资源的获取,而不是阻止跨域的请求,请求可以正常发出,但返回的内容被阻止,无法让JS脚本获取 例子: 1.<script>.<img>.<iframe>.<link>等标签都能跨域加载内容,但无法对外发送

禁用浏览器同源策略的方法

前后联调的时候总会涉及到跨域,平时我们跨域主要的方法是通过cors进行跨域,但是通过cors进行跨域有的时候会涉及到数据安全的问题,这时候我们可以通过禁用本地浏览器的同源策略来进行跨域的联调 ie的禁用同源策略设置,进入ie的网际网路选项设置,然后选择安全性,再选择自订等级,然后下拉,找到「存取跨网络的资料来源」,选择启用即可. chrome的话可以通过在命令行,输入「chrome --disable-web-security」,它会自己再新开启一个实例,开启chrome的时候显示一系列黄色的文

浏览器同源策略及Cookie的作用域

所谓"同源"指的是"三个相同": 1.协议相同 2.域名相同 3.端口相同 当着三个地方相同才算同源 例如:http://www.example.com:8888/dir/page.html 协议是http:// 域名是www.example.com 端口是8888 采用同源策略的目的:是为了保证用户信息的安全,防止恶意的网站窃取数据.设想这样一种情况:A网站是一家银行,用户登录以后,又去浏览其他网站. 如果其他网站可以读取A网站的 Cookie,会发生什么?如果

浏览器同源策略,及跨域解决方案

一.Origin(源) 源由下面三个部分组成: 域名 端口 协议 两个 URL ,只有这三个都相同的情况下,才可以称为同源. 下来就以 "http://www.example.com/page.html" 这个链接来比较说明: 对比URL 结果 原因 http://m.example.com/page.html 不同源 域名不同 https://www.example.com/page.html 不同源 协议不同 http://www.example.com:8080/page.htm

浏览器同源策略与ajax跨域方法汇总

原文 什么是同源策略 如果你进行过前端开发,肯定或多或少会听说过.接触过所谓的同源策略.那么什么是同源策略呢? 要了解同源策略,首先得理解“源”.在这个语境下,源(origin)其实就是指的URL.所以,我们需要先理解URL的组成.看看这个URL: http://www.jianshu.com/p/bc7b8d542dcd 我们可以将它拆解为下面几个部分协议.域名和路径: http :// www.jianshu.com /p/bc7b8d542dcd ${protocol}:// ${host

【Python-Django】浏览器同源策略

1995年,同源政策由 Netscape 公司引入浏览器.目前,所有浏览器都实行这个政策. 同源策略是浏览器的一个安全功能,不同源的客户端脚本(js文件)在没有明确授权的情况下,不能读写对方资源.只有同一个源的脚本赋予dom.读写cookie.session.ajax等操作的权限. url由协议.域名.端口和路径组成,如果两个url的协议.域名和端口相同,则这两个url是同源的. url 是否同源 原因 http://www.example.com/dir2/other.html 是 协议.端口

浏览器同源策略的概念?

摘录知乎的回答: 同domain(或ip),同端口,同协议视为同一个域,一个域内的脚本仅仅具有本域内的权限,可以理解为本域脚本只能读写本域内的资源,而无法访问其它域的资源.这种安全限制称为同源策略.