Ajax(jquery)

一.AJAX简介

AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML,现在更多使用json数
AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
  a.同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
  b.异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。
    AJAX除了异步的特点外,还有一个就是:浏览器页面局部刷新;(这一特点给用户的感受是在不知不觉中完成请求和响应过程
总体来说:AJAX两个特点:异步请求和局部刷新

在js+Ajax中,要区别版本信息,在jquery中不需要。

二.AJAX使用

Ajax用jquery实现主要有三个API:$.ajax()/$.get()/$.post()

1.$.ajax()

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    $.ajax({
        url:"/xx/",
        data:{a:1,b:2},
        type:"POST",
        processDate:false,            //data数据不进行转码(默认是true,是进行转码的)
        traditional:true,             //如果data数据中还有其他迭代:data:{a:1,b:[3,4]},传给服务端的数据为{'a':['1'],'b[]':['3','4']},traditional:true是改变这种情况,{'a':['1'],'b':['3','4']
        success:function(data){       //回调函数:当某个动作完成后会自动触发的一个函数(在这里是等浏览器服务端交互完成后接受服务端发来的信息)
            console.log(data);
            console.log(arguments);   //打印函数的参数
        }
    });
    $.ajax({
        url:'/xx/',
        data:$("#f1").seralize(),//发送所有能提交的数据
        traditional:true //如果是多选框,要加上这句
    })

</script>
</body>
</html>

2.$.get()

$.get("/xx/",function(data){           //data是服务端Httpresponse返回的对象,此为回调函数
    console.log(data)
});

3.$.post()

$.post(url, [data], [callback], [type]) //type: text/html/json/script type指定什么类型,如果接受到服务端的数据类型不对,那么回调函数不执行

$.post("/xx/",{name:"高玉坤"},function(data,contentType,jqy){      //参数四type:用来查看返回的是否是指定类型,如果不是则不执行回调函数
        console.log(arguments);
        console.log(data);             //高玉坤
        console.log(contentType);      //success/err
        console.log(jqy);              //
    });

4.$.getJSON()

$.get()的最后一个type参数必须是json类型

5.$.getScript()     #引用另一个js文件中的某种方法

$.getScript("/xx.js/",function(){
   alert(add(1,3)) ;
})

###xx.js###
function add(x,y){
  return x+y;  
}

三.AJAX请求设置csrf_token

在ajax设置csrf_token之前,我们先了解一下csrf攻击及其基本原理。

简单了解:

django 第一次响应来自某个客户端的请求时,会在服务器端随机生成一个 token,把这个 token 放在 cookie 里。然后每次 POST 请求都会带上这个 token。
token字符串的前32位是salt, 后面是加密后的token, 通过salt能解密出唯一的secret。检验token时,只比较secret是否和cookie中的secret值一样,而不是比较整个token
django会验证表单中的token(form表单中的{%csrf_token%}会生成一个隐藏的input标签:<input type="hidden" name="csrfmiddlewaretoken" value="WncCS9HKnajyZkHWnBesEeOnEW8VPiMRnTQqr1Ua1e1PSqhdhlE07VcCr4lVjTPo">)和cookie中token是否能解出同样的secret,secret一样则本次请求合法。

1.CSRF攻击原理及防范

CSRF 全拼为 Cross Site Request Forgery, 跨站请求伪造.CSRF指的是攻击者盗用了你的身份,以你的名义发送恶意的请求,给你造成个人隐私泄露及财产安全.

CSRF攻击原理

①用户正常登录A银行网站,
②A网站返回cookie信息给用户,浏览器保存cookie信息
③在A网站没有退出登录的情况下(或者说cookie信息没过期), 登录了恶意网站B
④恶意网站B,提前准备好转账表单或者其它请求 ,将其隐藏. 把提交到A网站的按钮设置为一个"领取优惠券"的图片链接.用户 点击链接
⑤在用户主观未知的情况下,访问A网站,此时浏览器会自动携带cookie信息
⑥A网站识别到cookie信息,默认为是用户本人做出的请求,根据请求做出相应的操作.
⑦用户收到损失.

CSRF如何防范

 在请求参数中加入一个混淆字符串csrf_token.
简单来说,服务器在接受到请求后, 返回给用户两个csrf_token值, 一个放在cookie信息中,浏览器会保存,下次请求的时候浏览器自动携带.  一个放在前端页面中(例如:表单域或者ajax的请求头中), 当用户再次向服务器发送数据的时候,  服务器会对比cookie中和前端页面中的csrf_token值,如果一样,证明是用户操作,如果不一样,证明是非法操作.
恶意网站B因为页面是提前写好的,无法获取到csrf_token值(cookie同源策略),所以服务器接受到请求的时候,会显示非法操作,从而保证了用户个人信息的安全.解决了csrf攻击

2.AJAX请求设置csrf_token

方式一:

在data中添加键值对:csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val()

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="{% static 'js/jquery-3.4.1.min.js' %}"></script>
</head>
<body>
<form action="">
    {% csrf_token %}   //生成隐藏的input标签<input type="hidden" name="csrfmiddlewaretoken" value="WncCS9HKnajyZkHWnBesEeOnEW8VPiMRnTQqr1Ua1e1PSqhdhlE07VcCr4lVjTPo">
    <input type="text" id="username" name="username">
    <input type="password" id="password" name="password">
    <input type="button" value="提交" id="submit">
</form>

<script>
    $("#submit").click(function () {
        $.ajax({
            url:"/test/",
            type:"post",
            data:{
                username:$("#username").val(),
                password:$("#password").val(),
                csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val(),  //取出{%csrf_token%}生成的input标签的val值
            },
            success:function (data) {
                alert(data);
            }
        })
    });
</script>
</body>
</html>

方式二:和方式一类似

$.ajax({
    data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
});

方式三:

通过获取返回的cookie的字符串放置在请求头中发送

注意:需要引入jquery.cookie.js的插件

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="{% static 'js/jquery-3.4.1.min.js' %}"></script>
    <script src="https://cdn.bootcss.com/jquery-cookie/1.3.1/jquery.cookie.js"></script>
</head>
<body>
<form action="">
    {% csrf_token %}
    <input type="text" id="username" name="username">
    <input type="password" id="password" name="password">
    <input type="button" value="提交" id="submit">
</form>

<script>
    $("#submit").click(function () {
        $.ajax({
            headers:{"X-CSRFToken":$.cookie('csrftoken')},
            url:"/test/",
            type:"post",
            data:{
                username:$("#username").val(),
                password:$("#password").val(),
            },
            success:function (data) {
                alert(data);
            }
        })
    });
</script>
</body>
</html>

四.文件上传

1.form表单文件上传

html中form表单必须写enctype="multipart/form-data"

<form action="/file_test/" method="post" enctype="multipart/form-data">  //enctype必须写
    <input type="file" id="file" name="file">
    <input type="submit" id="submit">
</form>

views.py

def file_test(req):
    if req.method == "GET":
        return render(req,"file.html")
    else:
        file = req.FILES.get("file")            #通过req.FILES.get("file")得到文件对象
        with open(file.name, 'wb') as f:
            for chunk in file.chunks():
                f.write(chunk)
        return HttpResponse("OK")

2.ajax文件上传

html文件中new FormData()对象。

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="{% static 'js/jquery-3.4.1.min.js' %}"></script>
    <script src="https://cdn.bootcss.com/jquery-cookie/1.3.1/jquery.cookie.js"></script>
</head>
<body>
<form action="">
    {% csrf_token %}
    <input type="file" id="file" name="file">
    <input type="text" id="username" name="username">
    <input type="submit" id="submit">
</form>

<script>
    $("#submit").click(function () {
        var formdata = new FormData();   //新建FormData()对象
        formdata.append("username",$("#username").val());  //给FormData对象添加键值对     formdata.append("file",$("#file")[0].files)
        formdata.append("file",$("#file")[0].files[0]); //获取第一个文件对象
        $.ajax({
            headers:{"X-CSRFToken":$.cookie('csrftoken')},
            url:"/file_test/",
            type:"post",
            data:formdata,  //将formdata对象传给后端
            processData:false,  //必写
            contentType:false,  //必写
            success:function (data) {
                alert(data);
            }
        })
    });
</script>
</body>
</html>

views.py写法和form表单提交一样

def file_test(req):
    if req.method == "GET":
        return render(req,"file.html")
    else:
        username = req.POST.get("username")
        file = req.FILES.get("file")
        with open(file.name, 'wb') as f:
            for chunk in file.chunks():
                f.write(chunk)
        return HttpResponse("OK")

五.AJAX和Django基于json交互

 数据类型转换图解:

1.最原始方法

ajax通过JSON.parse()或JSON.stringfiy()转换,django通过json.dumps()和json.loads()转换

views.py

def json_test(req):
    if req.method == "GET":
        return render(req,"json_test.html")
    else:
        dic = {"user":"root","pwd":123,"name":"急急急"}
        dic = json.dumps(dic,ensure_ascii=True)
        return HttpResponse(dic)

html中

<script>
    $("#submit").click(function () {
        $.ajax({
            headers:{"X-CSRFToken":$.cookie('csrftoken')},
            url:"/json_test/",
            type:"post",
            data:{"f":"f"},
            success:function (data) {
                data = JSON.parse(data);
                console.log(data);
                console.log(typeof data); //object对象
            }
        })
    });
</script>

2.在django中设置content_type='application/json'

通过设置content_type='application/json',ajax得到的数据不用再进行parse转换

views.py

def json_test(req):
    if req.method == "GET":
        return render(req,"json_test.html")
    else:
        dic = {"user":"root","pwd":123,"name":"急急急"}
        dic = json.dumps(dic,ensure_ascii=True)
        return HttpResponse(dic,content_type='application/json')

html中

<script>
    $("#submit").click(function () {
        $.ajax({
            headers:{"X-CSRFToken":$.cookie('csrftoken')},
            url:"/json_test/",
            type:"post",
            data:{"f":"f"},
            success:function (data) {
                console.log(data);  
                console.log(typeof data);   //object对象
            }
        })
    });
</script>

3.JsonResponse

views.py

非字典类型的JsonResponse(retdata,safe=False)

from django.http import JsonResponse
def json_test(req):
    if req.method == "GET":
        return render(req,"json_test.html")
    else:
        dic = {"user":"root","pwd":123,"name":"急急急"}
        # dic = json.dumps(dic,ensure_ascii=True)
        # return HttpResponse(dic,content_type='application/json')
        return JsonResponse(dic)  #相当于上述两行代码

html中

<script>
    $("#submit").click(function () {
        $.ajax({
            headers:{"X-CSRFToken":$.cookie('csrftoken')},
            url:"/json_test/",
            type:"post",
            data:{"f":"f"},
            success:function (data) {
                console.log(data);            //不用进行转换
                console.log(typeof data);  //直接得到object对象
            }
        })
    });
</script>

  

posted @ 2018-05-14 19:16  MISF  阅读(317)  评论(0编辑  收藏  举报
     JS过度和变形效果演示   
  
    html5.png