Ajax

一 Ajax简介

    翻译成中文就是异步的JavascriptXML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML,现在更多使用json数据)。AJAX 不是新的编程语言,而是一种使用现有标准的新方法.

  特点:

    1.异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。

    2.浏览器页面局部刷新;(这一特点给用户的感受是在不知不觉中完成请求和响应过程)

  

  2.示例

login.html里面内容

{% load static %}
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <!--      告诉浏览器安装IE的最高版本渲染浏览器-->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <!--      整个网站和等比缩放,目的兼容:移动端,web端。可以完整访问网站-->
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>标题</title>
    <!-- Bootstrap  引入文件 -->
    <link href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}" rel="stylesheet">

</head>
<body>
<h1>你好,欢迎来到登录页面</h1>

<form action="/login/" method="post">
    {% csrf_token %}
    用户名 <input type="text" id="username" name="username">
    密码 <input type="password" id="pwd" name="password">
{#    <input type="submit" id="btn">#}
{#    <button>提交</button>#}
    <input type="button" id="btn" value="确认">
  <span id="error" style="color:red;font-size:12px"><\span>
</form> {#<button id="btn">提交</button>#} <script src="{% static 'jquery-3.5.1.js' %}"></script> <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script> <script> $("#btn").click(function () { $.ajax({ url:'/login/',//方式1:直接获取请求地址不要忘了加双引号或者单引号 {#url:'{% url "login" %}',//方式2:通过url以及别名获取地址#} type:'post', data:{ uname:$('#username').val(), pwd:$('#pwd').val(), csrfmiddlewaretoken:$('[name=csrfmiddlewaretoken]').val(), //方式1:直接获取。因为我们表单中使用csrf_token,这个html文档中就是一个p标签,name属性等于csrfmiddlewaretoken,他的value值就是crstoken,因此我们可以通过js获取值 {#csrfmiddlewaretoken:'{% csrf_token %}',}//方式2:通过url以及别名获取地址#} }, //res就是返回的响应数据 success:function (res) { var retStr = JSON.parse(res);//json序列化 if (retStr['code']===302){ $("#error").text(retStr['msg']); }else if(retStr['code']===0){ location.href = retStr['login_url'] } console.log(retStr,typeof retStr) } }) }) </script> </body> </html>

  views.py里面的内容

from django.shortcuts import render,HttpResponse,redirect
from django.views import View
# Create your views here.

import json


class LoginView(View):

    def get(self,request):
        return render(request,'login.html')

    def post(self,request):
        # name = request.POST.get('username')
        # pwd = request.POST.get('pwd')
        #ajax data里面的键来获取数据
        name = request.POST.get('uname')//必须使用ajax传的data里面参数名称来获取
        pwd = request.POST.get('pwd')

        if name=='zxb' and pwd =='123':
            # return render(request,'index.html')
            ret = {'code':0,'login_url':'/index/'}
            return HttpResponse(json.dumps(ret))
        else:
            # ret = {'code':302,'redirect_url':'/login/'}
            ret = {'code':302,'msg':'用户名或者密码错误!!!'}
            return HttpResponse(json.dumps(ret))

def index(request):
    return render(request,'index.html')

  urls.py里面的内容

from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login/', views.LoginView.as_view(),name='login'),
    url(r'^index/', views.index,name='index'),
]

  注意:如果我们的ajax的js代码写在js文件中,我们html通过引入来执行js代码,我们就不可以使用  url:'{% url "login" %},csrfmiddlewaretoken:'{% csrf_token %}',这种形式因为我们js文件中不认识这些,这些只是在html文件中才可以使用,如果要在js中使用我们就要用方式1。如下就是js文件中代码

$("#btn").click(function () {
        $.ajax({
            url:'/login/',
            //url:'{% url "login" %}',
            type:'post',
            data:{
             uname:$('#username').val(),
             pwd:$('#pwd').val(),
             csrfmiddlewaretoken:$('[name=csrfmiddlewaretoken]').val(),
             //csrfmiddlewaretoken:'{% csrf_token %}',
            },
            //res就是返回的响应数据
            success:function (res) {
                var retStr = JSON.parse(res)
                if (retStr['code']===302){
                    var spanEle = document.createElement('span');
                    $(spanEle).text(retStr['msg']);
                    $('form').append(spanEle);

                }else if(retStr['code']===0){
                    location.href = retStr['login_url']
                }
                console.log(retStr,typeof retStr)
            }

        })
    })

 

4.AJAX的优缺点

    优点:

      1.AJAX使用JavaScript技术向服务器发送异步请求;

      2.AJAX请求无须刷新整个页面;

      3.因为服务器响应内容不再是整个页面,而是页面中的部分内容,所以AJAX性能

二Ajax发送各种请求方法以及视图函数解析传过来的数据

  1.Ajax不指定请求方式的情况下默认

 

 

四 Ajax文件上传

  请求头ContentType

    ContentType指的是请求体的编码类型,常见的类型共有3种

    1 application/x-www-form-urlencoded

      这应该是最常见的 POST 提交数据的方式了。浏览器的原生 <form> 表单,如果不设置 contentType 属性,那么最终就会以 默认格式application/x-www-form-urlencoded 方式提交数据,ajax默认也是这个。请求类似于下面这样(无关的请求头在本文中都省略掉了):

   

视图函数解析传递的数据直接使用JsonResponse(ret)来传递数据。使用request.Post,request.Get来获取数据,因为django内置的已经给我们解析了,直接获取。

 

2 multipart/form-data(用于上传文件使用)

          这又是一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让 <form> 表单的 contentType 等于 multipart/form-data,form表单不支持发json类型的contenttype格式的数据,而ajax什么格式都可以发,也是ajax应用广泛的一个原因。直接来看一个请求示例:(了解)

1.普通form表单上传文件

html代码:form表单上传文件必须要写enctype="multipart/form-data",不然无法上传文件。

 

 

<form action="{% url 'upload' %}" method="post" enctype="multipart/form-data">
       头像:<input type="file" name="head_pic">
        用户名:<input type="text" name="userName">
        <input type="submit">
</form>

 

2.ajax上传文件

html代码

  1.不需要要form标签,因为ajax提交数据,与form提交数据无关。

  2.首先要创建var formdata = new FormData();对象就,将需要传的参数使用append方法传入。

  3. 必须要写contentType:false,processData:false,不写会报错。

ajax上传文件:<input type="file" id="file">
ajax用户名:<input type="text" id="uname">
<button id="btn">提交</button>
<script src="{% static 'jquery-3.5.1.js' %}"></script>
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
<script>
    $("#btn").click(function () {
        var formdata = new FormData();
        formdata.append('username',$("#uname").val());
        formdata.append('head_pic',$("#file")[0].files[0])
        formdata.append('csrfmiddlewaretoken',$('[name=csrfmiddlewaretoken]').val())
        $.ajax({
            url:"{% url 'upload' %}",
            type:"post",
            data:formdata,
            //下面两个必须写,不写就报错
            contentType:false, //不设置内容类型
            processData:false, //不设置数据
            success:function (res) {
                console.log(res);
            }

        })
    })
    
</script>

传递file参数如下图:

 

 

 url代码

    url(r'^upload/', views.upload,name='upload'),

视图函数获取前端数据

  1.使用request.FILES获取一个传过来的对象,通过get方法根据key获取对应的值。注意get("file名称")获取的是上传的文件的文件句柄,因此我们可以循环写入获取文件。

 

import os
def upload(request):
    if request.method=='GET':
        return render(request,'uploadFile.html')
    else:
        print(request.POST) #<QueryDict: {'head-pic': ['p01.png'], 'userName': ['zxb']}>
        print(request.FILES) #<MultiValueDict: {'head-pic': [<InMemoryUploadedFile: p01.png (image/png)>]}> 内存中的文件对象
        #读取文件保存到本地
        file_obj = request.FILES.get('head_pic') #返回一个文件对象(文件句柄)
        print(file_obj) #p01.png 为什么对象打印出来文件名字,因为里面有——str--方法
        print(file_obj.name) #p01.png
        file_name = file_obj.name
        file_path = os.path.join(BASE_DIR,'statics','picture',file_name)
        print(file_path)
        #写文件方式1
        # with open(file_path,'wb') as f: #每次读取的data不是固定长度的,和读取其他文件一样,每次读一行,识别符为\r  \n  \r\n,遇到这几个符号就算是读了一行
        #     for i in file_obj:
        #         f.write(i)
        #写文件方式2:
        with open(file_path,'wb') as f:
            for chunks in file_obj.chunks(): ##chunks()默认一次返回大小为经测试为65536B,也就是64KB,最大为2.5M,是一个生成器
                f.write(chunks)

        return HttpResponse("ok")

 

 

 3. contentType:"application/json"

    json格式请求数据传递到视图函数数据格式为json

    $.ajax({
        url:"{% url 'data' %}",
        type:'post',
        data:JSON.stringify({k1:'v1',k2:'v2'}),
        contentType:"application/json",
        success:function (res) {
            console.log(res)
            /*for(var i in res){
            }*/
            $.each(res,function (k,v) {
                console.log(k,v) //k(索引),v(数值)
                var liStr='<li>'+v.toString()+'</li>' //toString数字转字符串方法
                $("ul").append(liStr)
            })
        }
    })

  视图函数需要解析ajax传过来的参数,因为视图函数接收到数据格式为byte类型,需要转换,并且需要反序列化,才可以正常的取值操作。

def data(request):
    li=[11,22,33]
    print(request.POST) #<QueryDict: {}>
    print(request.body) #b'{"k1":"v1","k2":"v2"}'
    para =request.body.decode('utf-8')
    print(para,type(para)) #{"k1":"v1","k2":"v2"} <class 'str'>
    para = json.loads(para)
    print(para,type(para)) #{'k1': 'v1', 'k2': 'v2'} <class 'dict'>
    return JsonResponse(li,safe=False)

五 关于json

  1.js的stringify与parse方法

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

JSON.parse('{"name":"chao"}');

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

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

2.通过json学列化时间日期格式数据的时候需要注意,不能直接序列化,使用下面的类就可以进行序列化

import json
from datetime import datetime
from datetime import date

#对含有日期格式数据的json数据进行转换
class JsonCustomEncoder(json.JSONEncoder):
    def default(self, field):
        if isinstance(field,datetime):
            return field.strftime('%Y-%m-%d %H:%M:%S')
        elif isinstance(field,date):
            return field.strftime('%Y-%m-%d')
        else:
            return json.JSONEncoder.default(self,field)

d1 = datetime.now()
dd = json.dumps(d1,cls=JsonCustomEncoder)
print(dd)

 

 

 

 

 

三 Ajax请求设置csrf_token

  方式1

    通过获取隐藏的input标签中的csrfmiddlewaretoken值,放置在data中发送。

$.ajax({
  url: "/cookie_ajax/",
  type: "POST",
  data: {
    "username": "chao",
    "password": 123456,
    "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val()  // 使用jQuery取出csrfmiddlewaretoken的值,拼接到data中
  },
  success: function (data) {
    console.log(data);
  }
})

方式2

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

 

方式3(后面再说)

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

    注意:需要引入一个jquery.cookie.js插件。

<script src="{% static 'jquery.cookie.js' %}"></script>
    $("#btn").click(function () {
        $.ajax({
            url: "{% url 'test' %}",
            type: 'post',
            {#方式2:ajax自己发送cookie#}
            headers:{
                "X-CSRFToken":$.cookie('csrftoken')
            },
            data:{
                usename:$("#usename").val(),
                {##方式1:#}
                {#csrfmiddlewaretoken:$('[name=csrfmiddlewaretoken]').val()#}
                
            },
            success:function (response) {
                console.log(response)
            }

        })
    })

 

jquery.cookie.js插件获取步骤:

  1.下载与引入:jquery.cookie.js基于jquery;先引入jquery,再引入:jquery.cookie.js;下载:http://plugins.jquery.com/cookie/

  

 

   2.解压下载包,找到下面文件,放到项目中

 

 

 

  jquery操作cookie方法:https://www.cnblogs.com/zhuxibo/p/14702067.html

 

posted @ 2021-04-08 11:46  西西cc  阅读(60)  评论(0编辑  收藏  举报