zoukankan      html  css  js  c++  java
  • Django——Ajax相关

     Ajax简介

    AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML,现在更多使用json数据)。

    • 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
    • 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。
      AJAX除了异步的特点外,还有一个就是:浏览器页面局部刷新;(这一特点给用户的感受是在不知不觉中完成请求和响应过程)

    AJAX应用场景

    • 索引擎根据用户输入的关键字,自动提示检索关键字。

    • 还有一个很重要的应用场景就是注册时候的用户名的查重。

    • 其实这里就使用了AJAX技术!当文件框发生了输入变化时,使用AJAX技术向服务器发送一个请求,然后服务器会把查询到的结果响应给浏览器,最后再把后端返回的结果展示出来

      • 整个过程中页面没有刷新,只是刷新页面中的局部位置而已!

      •  当请求发出后,浏览器还可以进行其他操作,无需等待服务器的响应!

      • 整个过程中页面没有刷新,只是局部刷新了;

      • 在请求发出后,浏览器不用等待服务器响应结果就可以进行其他操作;

    AJAX的优缺点

    优点:

    • AJAX使用Javascript技术向服务器发送异步请求
    • AJAX无须刷新整个页面
    • 因为服务器响应内容不再是整个页面,而是页面中的部分内容,所以AJAX性能高;

    缺点:

    • 每个点击即请求一次,服务端的压力会增大。 

    知识储备:

    需要的基础知识

    • HTML / XHTML

    • CSS

    • JavaScript / DOM

    什么是JSON?

    • JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation)

    • JSON 是轻量级的文本数据交换格式

    • JSON 独立于语言 *

    • JSON 具有自我描述性,更易理解

     * JSON 使用 JavaScript 语法来描述数据对象,但是 JSON 仍然独立于语言和平台。JSON 解析器和 JSON 库支持许多不同的编程语言。

     

    stringify与parse方法:

    • JavaScript中关于JSON对象和字符串转换的两个方法:

    • JSON.parse(): 用于将一个 JSON 字符串转换为 JavaScript 对象 

    1 JSON.parse('{"name":"Q1mi"}');
    2 JSON.parse('{name:"Q1mi"}') ;   // 错误
    3 JSON.parse('[18,undefined]') ;   // 错误

      JSON.stringify(): 用于将 JavaScript 值转换为 JSON 字符串。

    JSON.stringify({"name":"Q1mi"})

    Django项目中如何使用json:

    • 首先前端需要一个正确的序列化后的数据

    • 注意:contentType:"application/json"一旦设定,data必须是json字符串,不能是json对象

    • contentType:默认值:"application/x-www-form-urlencoded"。发送信息至服务器时内容编码类型。用来指明当前请求的数据编码格式;urlencoded:?a=1&b=2;如果想以其他方式提交数据,比如contentType:"application/json",即向服务器发送一个json字符串;

    前端代码:

    $("#b1").click(function () {
            console.log(dict);
            json_obj = JSON.stringify({'dict':dict, 'data':$("#a1").attr("value")});
            console.log(json_obj);
            $.ajax({
                url: "/index/",
                type: "POST",
                data: json_obj,
                contentType:"application/json",
                success: function (data) {
                    window.location.href = "/index/";
                }
            })
        })
    • 后端解析数据
    • request_json = json.loads(request.body)

    jQuery实现的AJAX:

    AJXA语法

    • 一般请求
    $.ajax({
        url: "/index/",            #往哪发送请求
        type:"POST",              #请求的方法
        data:{name:"dream",age:18},      #请求数据
        success:function(data){
        #请求被正常响应时,自动执行的回调函数,data为返回值                  
         }         
        })
    • 提交携带文件类型的请求
    var formData = new FormData(); #生成一个FormData
    var =fileobj = $("#f1")[0].files[0]#得到一个用户选中的文件对象
    formData.append("f1",fileobj) # 向formData对象中添加间值对数据
    $.ajax({
        url: "/index/",     #往哪发送请求
        type:"POST",        #请求的方法
        processData: false, #不让jQuery处理我的数据
        contentType: false, #不让jQuery设置请求头
        data:formData,      #请求数据
        success:function(data){
        #请求被正常响应时,自动执行的回调函数,data为返回值
                    }
                })

    $.ajax参数

    • async

      • 类型:Boolean

      • 默认值: true。默认设置下,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为 false。

      • 注意,同步请求将锁住浏览器,用户其它操作必须等待请求完成才可以执行。

    • data

      • 类型:String

      • 发送到服务器的数据。将自动转换为请求字符串格式。GET 请求中将附加在 URL 后。查看 processData 选项说明以禁止此自动转换。必须为 Key/Value 格式。如果为数组,jQuery 将自动为不同值对应同一个名称。如 {foo:["bar1", "bar2"]} 转换为 '&foo=bar1&foo=bar2'。

    • type

      • 类型:String默认值: "GET")。请求方式 ("POST" 或 "GET"),

      • 默认为 "GET"。注意:其它 HTTP 请求方法,如 PUT 和 DELETE 也可以使用,但仅部分浏览器支持。

    • url

      • 类型:String

      • 默认值: 当前页地址。发送请求的地址。

    • processData

      • 类型:Boolean

      • 默认值: true。默认情况下,通过data选项传递进来的数据,如果是一个对象(技术上讲只要不是字符串),都会处理转化成一个查询字符串,以配合默认内容类型 "application/x-www-form-urlencoded"。如果要发送 DOM 树信息或其它不希望转换的信息,请设置为 false。

      • 注意:如果不需要jQuery去处理发送的数据是,请修改为false
    • contentType

      • 类型:String

      • 默认值: "application/x-www-form-urlencoded"。发送信息至服务器时内容编码类型。默认值适合大多数情况。如果你明确地传递了一个 content-type 给 $.ajax() 那么它必定会发送给服务器(即使没有数据要发送)。

      • 注意:如果需要jQuery不去设置Content-Type请求头,则设置默认值为false。
    • success

      • 类型:Function

      • 请求成功后的回调函数。

      • 参数:由服务器返回,并根据 dataType 参数进行处理后的数据;描述状态的字符串。

      • 这是一个 Ajax 事件。

    jQuery实现AJAX上传文件:

    • 需要注意:不适用form表单提交数据时,需要在函数内使用 FormData() 方法生成一个表单对象

    • var formData = new FormData();

    #  上传文件
    def upload(request):
        if request.method == 'POST':
            file_obj = request.FILES.get('file',None)
            if file_obj:
                with open(file_obj.name,'wb') as f:
                    for chunk in file_obj.chunks():
                        f.write(chunk)
                return HttpResponse("上传成功")
            return render(request,'upload.html')
        return render(request,'upload.html'
    View Code
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>上传文件</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
    </head>
    <body>
     
    <input id="i1" type="file">
    <button id="b1">点我</button>
     
    <script src="/static/jquery-3.3.1.min.js"></script>
    <script src="/static/setupAjax.js"></script>
    <script>
        $("#b1").click(function () {
            // 生成表单对象
            var formData = new FormData();
            formData.append("file",$("#i1")[0].files[0]);
            $.ajax({
                url: "/upload/",
                type: "POST",
                // 告诉jQuery不要去处理发送的数据
                processData: false,
                // 告诉jQuery不要去设置Content-Type请求头
                contentType: false,
                data: formData,
                success:function (data) {
                    console.log(data)
                }
                })
        })
    </script>
    </body>
    </html>
    View Code

    jQuery实现最基础监控注册用户是否注册

    • 注意:尽量不要使用input事件,因为input事件是实时监听,会给服务器造成压力。

    • 这里选用的是,失去焦点事件,blur

    前端代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>注册</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
        <style>
            .error {
                color: red;
            }
        </style>
    </head>
    <body>
    <div>
        <label for="i1">用户名</label>
        <input type="text" id="i1">
        <span class="error" id="s1"></span>
    </div>
    <div>
        <label for="p1">密码</label>
        <input type="password" id="p1">
    </div>
    <div>
        <button id="b1">提交注册</button>
    </div>
     
    <script src="/static/jquery-3.3.1.min.js"></script>
    <script>
        // 监控用户名输入框的焦点,只要i1失去焦点,就要把用户填写的往后台发送
        $("#i1").blur(function () {
            // 将s1的初始值设为空
            $("#s1").text("");
            // 获取i1的值,即用户输入的值
            var value = $(this).val();
            // 调用ajax
            $.ajax({
                // 提交到什么地方
                url: "/res2/",
                // 以什么方式提交
                type: "POST",
                // 传送到后台的数据
                data: {name: value},
                // 回调函数,data为返回值
                success: function (data) {
                    console.log(data);
                    if (data.no_ok) {
                        // 如果用户已存在
                        $("#s1").text(data.msg)
                    }
                }
            })
        })
    </script>
     
    </body>
    </html>
    View Code

    后端代码:

    def res2(request):
        from django.http import JsonResponse
        res = {"no_ok": 0}
        if request.method == 'POST':
            print(request.POST)
            user_name = request.POST.get('name')
            if user_name == 'dream':
                res = {"no_ok": 1, "msg": "用户已存在."}
            return JsonResponse(res)
        return render(request,'res2.html')
    View Code

    JS实现AJAX:

    <script>
        let b1Ele = document.getElementById("b1");
        b1Ele.onclick = function () {
            // 1. 生成xmlHttp对象
            let xmlHttp = new XMLHttpRequest();
            // 2. 调用xmlHttp的open方法设置请求相关配置项
            xmlHttp.open("POST", "/ajax_js/", true);
            // 3. 设置请求头
            xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            // 4. 调用send方法发送数据
            xmlHttp.send("username=dream&age=16");
            // 5. 处理返回的响应
            xmlHttp.onreadystatechange = function () {
                if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
                    alert(xmlHttp.responseText);
                }
            };
        }
    </script>

    AJAX请求如何设置csrf_token:

    如果不设置csrf_token,则无法往后端发送数据,点击查看详细

    方式一

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

     注意:需要在html中引入jquery.cookie.js插件

    •  导入<script src="/static/jquery.cookie.js"></script>
    • 从Cookie取csrf_token,并设置ajax请求头
    <script>
            $("#b1").click(function () {
            var name = $("#i1").val();
            var pwd = $("#p1").val();
            $.ajax({
                url: "/register/",
                type: "POST",
                headers: {"X-CSRFToken": $.cookie('csrftoken')},  // 从Cookie取csrf_token,并设置ajax请求头
                data: {name: name, pwd: pwd},
                success:function (data) {
                    if (!data.code){
                        // 登陆成功
                        location.href = data.data;
                    }
                }
            })
        })
    </script>

    方式二:

    手动把csrf_token的值取到,塞进请求的data中

     $("#b11").click(function () {
            // 点击之后要做的事儿
            $.ajax({
                url: "/ajax_test2/",
                type: "POST",
                data: {
                    i11: $("#i11").val(),
                    i22: $("#i22").val(),
                    // 取到csrf_token的值
                    csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val()
                },
                success: function (data) {
                    console.log(data);
                    $("#i33").val(data);
                }
            })
        });

    方式三:

    在一个单独的JS文件中,给$.ajax统一设置一下请求头

    • 导入自己写的js文件  setupAjax.js

     

    文件代码

    复制保存到js文件中,导入到html中即可使用

    /**
     * Created by oldboy on 2018/6/27.
     */
    function getCookie(name) {
        var cookieValue = null;
        if (document.cookie && document.cookie !== '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) === (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
    var csrftoken = getCookie('csrftoken');
    function csrfSafeMethod(method) {
      // these HTTP methods do not require CSRF protection
      return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    }
    $.ajaxSetup({
      beforeSend: function (xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
          xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
      }
    });

    注意事项:

    • 如果发送的data中,数据不是简单的字符串或数字,需要用JSON.stringify()转换成JSON字符串
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>json提交数据</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
    name<input type="text" id="n1">
    password<input type="password"  id="p1">
    <button id="b1">提交</button>
    <script src="/static/jquery-3.3.1.min.js"></script>
    <script src="/static/setupAjax.js"></script>
    <script>
        $("#b1").click(function () {
                $.ajax(
                    {
                        url:"login",
                        type:"POST",
                        // 告诉游览器我发送的是一个json数据
                        contentType:"application/json",
                        data:JSON.stringify({name:$("#n1").val(),pwd:$("#p1").val()}),
                        success:function (data) {
                            console.log(data)
                        }
                    }
                )
            }
        )
    </script>
    </body>
    </html>
    View Code

    反序列化

    import json
    json.loads(request.body)

    在求头中设置编码格式:

    • 常用的三种编码格式
    1 application/x-www-form-urlencoded
    2 json
    3 formdata
    • 告诉游览器我使用的是json编码格式

      

    • 如果不设置则会采用默认的

  • 相关阅读:
    Jest | expect常用匹配方法
    typescript | typeScript 笔记
    好用的思维脑图
    VSCode launch.json 配置详解
    各种语法技术栈文档汇总|api文档集合
    浏览器的运行机制
    js字符串转数字长度限制|超过长度有误差
    css对话框| 气泡框| css箭头
    nginx和php-fpm的用户权限
    mac安装redis拓展
  • 原文地址:https://www.cnblogs.com/xh-0205/p/9742220.html
Copyright © 2011-2022 走看看