Ajax


Ajax准備知識

Ajax介紹

AJAXAsynchronous Javascript And XML)翻譯成中文就是異步的JavascriptXML”。即使用Javascript語言與服務器進行異步交互,傳輸的數據為XML(當然,傳輸的數據不只是XML)。

Ajax並不是一門新的語言 它其實就是基於JS寫的一個功能模塊而已。

AJAX 最大的優點是在不重新加載整個頁面的情況下,可以與服務器交換數據並更新部分網頁內容。(這一特點給用戶的感受是在不知不覺中完成請求和響應過程)。

AJAX 不需要任何瀏覽器插件,但需要用戶允許JavaScript在瀏覽器上執行。

  • 同步交互:客戶端發出一個請求后,需要等待服務器響應結束后,才能發出第二個請求;
  • 異步交互:客戶端發出一個請求后,無需等待服務器響應結束,就可以發出第二個請求。
復制代碼
AJAX
    1、AJAX是什么
        前端向后端發送請求的方式

    2、前端向后端發送請求的方式
        1、直接在瀏覽器地址欄輸入URL訪問    -->GET
        2、點擊a標簽跳轉到指定頁面         -->GET
        3、form表單                      -->GET/POST
        4、AJAX                          -->GET/POST
復制代碼

AJAX的兩個關鍵點:局部刷新,異步請求

JQuery實現Ajax

案例:

頁面上有三個input框 一個按鈕
用戶在前兩個框中輸入數字 點擊按鈕保證頁面不刷新的情況下將數據發到后端做計算,然后將計算好的結果再發給前端展示到第三個input框中

復制代碼
<script>
    $('#d1').click(function () {
        //獲取兩個框里面的內容,朝后端提交異步請求
        //ajax基本語法
        $.ajax({
            // 1.指定朝哪個后端提交數據
            url:'',//控制數據的提交路徑 有三種寫法 跟form表單的action屬性一致
            // 2.指定當前請求方式
            type:'post',
            // 3.指定提交的數據
            data:{'i1':$('#i1').val(),'i2':$('#i2').val()},
            // 4.ajax是異步提交,所以需要給一個回調函數來處理返回結果
            success:function (data) { // data就是異步提交的返回結果
                //將異步提交的結果通過DOM操作渲染到第三個input框里
                {$('#i3').val(data)}
            }
        })
復制代碼

注意,Ajax提交數據需要把中間件注釋掉

  Views.py

def index(request):
if request.method =='POST':
i1 = request.POST.get('i1')
i2 = request.POST.get('i2')
# i1,i2是字符串類型,需要先做類型轉換
i3 = int(i1) + int(i2)
return HttpResponse(i3)
return render(request,'index.html')

Views.py

頁面展示:

content-type 編碼格式

form表單

 點開瀏覽器檢查Network 發現form表單傳輸的數據默認是urlencoded

 urlencoded數據格式:

  username=jason&password=123

 django后端針對該格式的數據 會自動解析並幫你打包到request.POST中

如果提交的是文件

 后端獲取的只是文件名

 formdata數據格式

 后端獲取的是文件對象

django后端針對符合urlencoded編碼格式數據(普通鍵值對)還是統一解析到request.POST中
而針對formdata文件數據就會自動解析放到request.FILES中

Ajax

Ajax默認的也是urlencoded編碼格式

Ajax還可以發json格式的數據

注意:前后端數據交互 編碼格式與數據格式一定要一致,不能騙人家!!!

復制代碼
    //發json格式
    $('#d2').on('click',function () {
    $.ajax({
        url:'',
        type:'post',
        // 修改content-Type參數
        contentType:'application/json', //把默認的urlencoded編碼格式改成json數據的格式
        data:JSON.stringify({'username':'jason','password':123}),  // 將數據序列化成json格式字符串
        success:function (data) {
            alert(data)
        }
    })
復制代碼

 由瀏覽器檢查可知,此時發的就是json數據了

 django后端針對json格式數據 並不會做任何的處理,而是直接放在request.body中,需要自己處理二進制的json格式

復制代碼
    import json 

    #自己處理json格式數據
    json_bytes = request.body
    #先解碼
    # json_str = json_bytes.decode('utf-8')
    #再反序列化
    # json_dict = json.loads(json_str)
    
    #擴展 json.loads能夠自動解碼並序列化
    json_dict = json.loads(json_bytes)
    print(json_dict,type(json_dict))
復制代碼

Ajax發送文件:

Ajax有一個內置對象FormData,既發可以普通鍵值對也可以發文件

復制代碼
        // ajax發送文件數據  需要借助於內置對象
    $('#d3').click(function () {
        // 1 需要先生成一個內置對象
        var myFormData = new FormData();
        // 2 傳普通鍵值對  當普通鍵值對較多的時候 我們可以利用for循環來添加
        myFormData.append('username','jason');
        myFormData.append('password',123);
        // 3 傳文件
        myFormData.append('myfile',$('#i1')[0].files[0]);  // 獲取input框內部用戶上傳的文件對象
        // 發送ajax請求
        $.ajax({
            url:'',
            type:'post',
            data:myFormData,
            // 發送formdata對象需要指定兩個關鍵性的參數

            processData:false,  // 讓瀏覽器不要對你的數據進行任何的操作
            contentType:false,  // 不要使用任何編碼格式 對象formdata自帶編碼格式並且django能夠識別該對象
            success:function (data) {
                alert(data)
            }
        })
    })
復制代碼

由下圖可知,此時就可以拿到文件對象和普通鍵值對了

序列化

Django內置的serializers

 前后端交互一般都是一個大字典,后端會給前端寫一個接口文檔,表明大字典內都有哪些鍵值對,然后前端根據字典就可以取到想要的值。

那么這個時候,就可以用Django給我們提供的序列化方式 serializers

復制代碼
#導入內置序列化模塊
from django.core import serializers 

def ab_se(request):
    #拿到用戶表里面的所有的用戶對象
    user_queryset = models.Userinfo.objects.all()
    #調用該模塊下的方法,第一個參數是你想以什么樣的方式序列化你的數據
    res = serializers.serialize('json',user_queryset)
    # return render(request,'ab_se.html',locals())
    '''
    or
    '''
    return HttpResponse(res)
復制代碼

 

 補充:上傳文件和json序列化

 

Ajax          XHR就是看ajax請求 content_type是前后端數據交互的一種格式text、html、applicaiton/json等等

```
特性:
    1.異步請求
    2.局部刷新

    $.ajax({
        url:'/login/',
        type:'post',
        data:{
            username:$('[name=username]').val(),
            password:$('[name=password]').val(),
            csrfmiddlewaretoken:$('[name=csrfmiddlewaretoken]').val(),
            
        },
        success:function(response){
            var response = JSON.parse(response); #反序列化
            response 視圖函數返回值
        }
                    
    })
    
```



# 今日內容



## 上傳文件

## form表單上傳文件
urlencoded 格式 name=xx&ss=ss...
```
<form action="/upload/" method="post" enctype="multipart/form-data"> # 重點
  {% csrf_token %}
  頭像: <input type="file" name="head-pic">
  用戶名: <input type="text" name="username">
  <input type="submit">
</form>


def upload(request):
    if request.method == 'GET':

        return render(request,'upload.html')
    else:
        print(request.POST)  #拿到的是post請求的數據,但是文件相關數據需要用request.FILES去拿
        print(request.FILES) #<MultiValueDict: {'head-pic': [<InMemoryUploadedFile: 1.png (image/png)>]}>
        file_obj = request.FILES.get('head-pic')
        print(file_obj)
        file_name = file_obj.name


        # f = open('xx.txt','rb')
        # with open('xx.txt','wb') as f2:
        #     for i in f:
        #         f2.write(i)
        import os
        path = os.path.join(settings.BASE_DIR,'statics','img',file_name)
        with open(path,'wb') as f:
            for i in file_obj:
                f.write(i)
            #for chunk in  file_obj.chunks():
            #    f.write(chunk)

        return HttpResponse('ok')


```



## ajax上傳文件

```


var formdata = new FormData();
formdata.append('user',$('#username').val())
formdata.append('csrfmiddlewaretoken',$('#csrfmiddlewaretoken').val())
formdata.append('file',$('#file')[0].files[0])
$.ajax({
    url:'/upload/',
    type:'post',
    data:formdata,
    success:function(response){
        response
    
    }

})

def upload(request):
    if request.method == 'GET':

        return render(request,'upload.html')
    else:
        print(request.POST)  #拿到的是post請求的數據,但是文件相關數據需要用request.FILES去拿
        print(request.FILES) #<MultiValueDict: {'head-pic': [<InMemoryUploadedFile: 1.png (image/png)>]}>
        file_obj = request.FILES.get('head-pic')
        print(file_obj)
        file_name = file_obj.name


        # f = open('xx.txt','rb')
        # with open('xx.txt','wb') as f2:
        #     for i in f:
        #         f2.write(i)
        import os
        path = os.path.join(settings.BASE_DIR,'statics','img',file_name)
        with open(path,'wb') as f:
            for i in file_obj:
                f.write(i)
            #for chunk in  file_obj.chunks():
            #    f.write(chunk)

        return HttpResponse('ok')



```



## JsonResponse

```
def index(request):

​    d1 = {'name':'chao'}

​    import json

​    return HttpResponse(json.dumps(d1))  -- success:function(res){ var a = JSON.parse(res) }

​    return HttpResponse(json.dumps(d1),content-type='application/json') --success:function(res){res--自定義對象,不需要自己在反序列化了}

​    return JsonResponse(d1)

​    d1 = [11,22]  #非字典類型的數據都需要加safe=False
return JsonResponse(d1,safe=False)
```



獲取多對多數據的時候

```
authors = request.POST.getlist('authors')
```



## 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)
```


from django.conf import settings 全局的設置,區別於用戶的設置

 form表單input標簽需要寫name屬性
 ajaxinput標簽不需要寫name屬性,因為與data里的鍵名有關
 
 $ajax({
 url:'/upload/',
 tyepe:'post',
 data:{aa:&('#name').val(), #django里request.POST.get(''aa')  #與input里提交數據不一樣
 })


date,datetime類型轉json  見xx.py

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM