Ajax之跨域请求

12345huangchun 2019-01-31 原文

Ajax之跨域请求

  一、引子

  我现在开启了两个django项目,分别叫Demo1和Demo2,Demo1中有一个路径‘http://127.0.0.1:8000/index/’,对应的视图是index视图返回一个index页面,页面中只有一个button按钮,按钮绑定了一个单击事件,点击之后会发送一个ajax请求,请求的路径为‘http://127.0.0.1:8001/ajax/’,Demo1的ip和端口号是:‘http://127.0.0.1:8000/’,Demo2的ip和端口号是:‘http://127.0.0.1:8001/’。前面一段描述就是在Demo1项目的一个页面向Demo2项目发送一个ajax请求,在Demo2有对应的路径和视图来处理请求,并返回值。我们运行一下。报错如下:

  这就是一个已拦截的跨域请求的错误,错误内容是CORS头少“Access-Control-Allow-Origin”。这就是我们用ajax发送一个跨域请求出现的错误,这就是今天我要处理的一个问题。

  二、同源策略

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

同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript的浏览器都会用这个策略。所谓的同源,即指:域名、端口、协议同时相同。比如说你用ajax发请求时,会检查你发送的请求是否发送路径是否ajax所在的JavaScript属于同源,即是两者的ip、端口、协议相同。如果不是同源,浏览器就会报错,提示拒绝访问。

  想要实现用ajax发送跨域请求有两种方式,一是jsonp,而是cors。

  三、基于JSONP的ajax跨域请求

  1,版本1

  我们在用script引入js代码,有时用的是网上路径,意思就是在我们的项目去请求其他项目的,如:

  这种情况下是可以请求成功的,于是,我们可以运用这一功能,给button按钮绑定事件,事件的功能是创建一个script标签,然后添加到页面上,这样当我们点击button按钮就会发送一个跨域请求,而且还是允许的。

  Demo1项目index.html页面上添加js代码:

function get_ele_script(url){
            var ele_script=$('<script>');
            ele_script.attr('src',url);
            ele_script.attr('id','ele_script');
            $('body').append(ele_script);
            $('#ele_script').remove()
        }
 $('.cli').click(function () {
            get_ele_script('http://127.0.0.1:8001/ajax/')
        })

  这样就成功用点击事件发送了一个跨域请求,在Demo2的视图中,有返回值,但如果我不定义返回的值,HTML文件就会报没有定义的错误,而且视图返回的值在前端页面是以变量的形式显示。

  Demo2项目的视图:

def ajax(request):
    dic={'name':'zhnag','age':46}
    dic_json=json.dumps(dic)
    return HttpResponse('f(%s)'%dic_json)

  此时,我们就应该在HTML文件中定义f()

function f(params) {
            console.log(params);
            console.log(typeof params);
        }

  这样,当我们点击button时,会往Demo2发送一个请求,Demo2会返回带参数的f(),由于已经定义了f()函数,所以当返回时会执行这个函数,这种方法就实现了发送跨域请求,然后接受返回值,并对返回值进行处理。

  2,版本2

  其实版本1在Demo2项目中把返回的函数名写死了,如果照版本1,所有来反问Demo2的浏览器都会得到一个叫f()的函数,我们在声明的时候也只能写成f()。其实我们可以这样在请求的时候把我们定义的函数名一起发过去,让他就给我返回我发送过去的函数,这样,我们定义函数名就可以随意了。

  Demo1项目的index.html页面上就应这样写:

function f(params) {
            console.log(params);
            console.log(typeof params);
        }
$('.cli').click(function () {
            get_ele_script('http://127.0.0.1:8001/ajax/?callbacks=f')

  Demo2项目的视图:

def ajax(request):
    a=request.GET.get('callbacks')
    dic={'name':'zhnag','age':46}
    dic_json=json.dumps(dic)
    return HttpResponse('%s(%s)'%(a,dic_json))

  3,版本3

  上面两个版本就没有基于ajax请求,这个版本就基于ajax发送跨域请求。

  Demo1项目下的index.html页面上:

function f(params) {
            console.log(params);
            console.log(typeof params);
        }
$('.cli').click(function () {
            $.ajax({
                url:'http://127.0.0.1:8001/ajax/callbacks=f',
                type:'GET',
                dataType:'jsonp',
            })
        })

  Demo2项目的视图:

def ajax(request):
    a=request.GET.get('callbacks')
    dic={'name':'zhnag','age':46}
    dic_json=json.dumps(dic)
    print(type(dic_json))
    return HttpResponse('%s(%s)'%(a,dic_json))

  4,版本4

  这也是基于ajax发送的跨域请求,只是比上一版本更简单。

  Demo1项目下的index.html:

function f(params) {
            console.log(params);
            console.log(typeof params);
        }
$('.cli').click(function () {
            $.ajax({
                url:'http://127.0.0.1:8001/ajax/',
                type:'GET',
                dataType:'jsonp',
                jsonp:'callbacks',
                jsonpCallback:'f'
            })
        })

  Demo2项目的视图:

def ajax(request):
    a=request.GET.get('callbacks')
    dic={'name':'zhnag','age':46}
    dic_json=json.dumps(dic)
    print(type(dic_json))
    return HttpResponse('%s(%s)'%(a,dic_json))

  5,版本5(终极版本)

  基于ajax的跨域请求,并把返回值给ajax的success。

  Demo1项目下的index.html:

$('.cli').click(function () {
            $.ajax({
                url:'http://127.0.0.1:8001/ajax/',
                type:'GET',
                dataType:'jsonp',
                jsonp:'callbacks',
                success:function (data) {
                    console.log(data)
                }
            })
        })

  Demo2项目下的视图:

def ajax(request):
    a=request.GET.get('callbacks')
    dic={'name':'zhnag','age':46}
    dic_json=json.dumps(dic)
    return HttpResponse('%s(%s)'%(a,dic_json))

  这个版本就比较简单,书写方便

  四、基于CORS的ajax跨域请求

  最开始,我们讲的报错是:CORS头少:‘Access-Control-Allow-Origin’,既然少一个,我们就加一个,就可以了,其实这种方式才是最常用。

  Demo1项目下的index.html:

$('.cli').click(function () {
            $.ajax({
                url:'http://127.0.0.1:8001/ajax/',
                type:'get',
                data:{'a':1},
                success:function (res) {
                    console.log(res)
                }
            })
        })

  Demo2项目下的视图:

def ajax(request):
    dic = {'name': 'zhnag', 'age': 46}
    http=HttpResponse(json.dumps(dic))
    http['Access-Control-Allow-Origin']='http://127.0.0.1:8000'     #这相当于加了一个白名单,对于‘http://127.0.01:8000’的跨域请求就允许通行
    return http

 

发表于 2019-01-31 20:58 W的一天 阅读() 评论() 编辑 收藏

 

版权声明:本文为12345huangchun原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/12345huangchun/p/10339812.html

Ajax之跨域请求的更多相关文章

随机推荐

  1. RSA算法在Python Django中的简单应用

    说明 RSA算法是当今使用最广泛,安全度最高的加密算法。 • RSA算法的安全性理论基础 [引]根据百科介绍, […]...

  2. 接口测试 – 什么是接口测试?

    本文为原创,有理解不当之处,还请指正   接口(API) – Application Progra […]...

  3. Java 类执行顺序 – zhuyongzhe

    Java 类执行顺序 1.如果父类有静态成员赋值或者静态初始化块,执行静态成员赋值和静态初始化块2.如果类有静 […]...

  4. 利用信息差赚钱,这个很赚的,很多你看不上觉得很普通的东西,在另一个行业也许就是香饽饽

    2020年的春节有些不同寻常,本来该采买年货,走亲访友的春节必备项目荡然无存。一夜之间,全国人民闭门不出,自觉 […]...

  5. 点击鼠标右键弹出错误提示:CrashHandler initialization error

    电脑重装系统后,什么都没有了,重装部分必须用的软件后,不管是在桌面还是在文件夹中,当点击鼠标右键时,总是弹出错 […]...

  6. 学习OpenCV——Gabor函数的应用

    学习OpenCV——Gabor函数的应用 2016-04-17 19:48  GarfieldEr007  阅 […]...

  7. 用python实现自动玩21点小游戏

    1. 背景 前段时间发现一个论坛上(https://npupt.com/blackjack.php)有21点小 […]...

  8. 【OpenCV-Python:实现人脸、人眼、嘴巴识别】实战(一) – 玉米fight

    【OpenCV-Python:实现人脸、人眼、嘴巴识别】实战(一)   AI时代的到来,手机上的APP开始应用 […]...

展开目录

目录导航