本篇博客介紹在 html 中使用 ajax 與後臺進行數據交互。css
ajax(Asynchronous Javascript And XML)翻譯成中文就是‘’異步 JavaScript 和 XML‘’。即便用 JavaScript 語言與服務器進行異步交互,傳輸的數據爲 XML(如今更多地使用 json)。html
ajax 除了異步的特色外,還有一個就是:瀏覽器頁面局部刷新。在頁面沒有進行刷新的狀況下進行數據交互。前端
優勢:python
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <script src="/static/jquery-3.3.1.js"></script> <title>regist</title> {# <link rel="stylesheet" href="/static/jquery-3.3.1.js">#} </head> <body> <p>用戶:<input type="text" id="name"></p> <p>密碼:<input type="password" id="pwd"></p> <p>確認密碼:<input type="password" id="tpwd"></p> <input type="button" id="submit" value="提交"><span id="error"></span> </body> <script> $('#submit').click(function () { console.log($('#submit')); {#$.ajax({#} {# url:'/regist/',#} {# type:'post',#} {# data:{name:$("#name").val(), pwd:$("#pwd").val(), tpwd:$("#tpwd")},#} {# success:function (data) {#} {# console.log(data)#} {# }#} $.ajax({ url:'/regist/', type:'post', data:{name:$("#name").val(), pwd:$("#pwd").val(), tpwd:$("#tpwd").val()}, success:function (data) { console.log(data) } }) }) </script> </html>
from django.http import JsonResponse from django.shortcuts import render, redirect from app01.models import * # Create your views here. def wrapper(func): def inner(*args, **kwargs): if args[0].method == 'GET': return func(*args, **kwargs) elif kwargs['contentType'] == 'application/json': import json args[0].POST = json.loads(args[0].body) return func(*args, **kwargs) else: return func(*args, **kwargs) return inner import json # json.loads() def regist(request): dic = {'status': 200, 'msg': None} print(request.body) if request.method == 'GET': return render(request, 'regist.html') else: print('/////') print(request.POST, 'dddd') name = request.POST.get('name') pwd = request.POST.get('pwd') tpwd = request.POST.get('tpwd') user = UserInfo.objects.filter(name=name).first() if user: dic['status'] = 100 dic['msg'] = '用戶已存在' return JsonResponse(dic) else: if name and pwd and tpwd: if pwd == tpwd: UserInfo.objects.create(name=name, pwd=pwd) dic['msg'] = '註冊成功' return JsonResponse(dic) else: dic['status'] = 101 dic['msg'] = '兩次密碼不同' return JsonResponse(dic) else: dic['status'] = 101 dic['msg'] = '密碼不正確' return JsonResponse(dic) @wrapper def login(request): dic = {'status': 200, 'msg': None} if request.method == 'GET': return render(request, 'login.html') else: name = request.POST.get('name') pwd = request.POST.get('pwd') user = UserInfo.objects.filter(name=name).first() if not user: dic['status'] = 100 dic['msg'] = '用戶不存在,請註冊' return JsonResponse(dic) else: if pwd == user.pwd: dic['msg'] = '登錄成功' return JsonResponse(dic) else: dic['status'] = 101 dic['msg'] = '密碼錯誤' return JsonResponse(dic)
$("#submit3").click(function () { $.ajax({ url: '/auth/', type: 'post', data: { 'user': $("#id_name").val(), 'password': $('#id_password').val() }, success: function (data) { {#console.log(data)#} var data=JSON.parse(data) if (data.user){ location.href='https://www.baidu.com' }else { $(".error").html(data.message).css({'color':'red','margin-left':'20px'}) } } }) } )
這是最多見的 POST 提交數據的方式了。瀏覽器的原生<form>表單,若是不設置 enctype 屬性,那麼最終會以 application/x-www-form-urlencoded方式提交數據。相似於下面:jquery
POST http://www.example.com HTTP/1.1 Content-Type: application/x-www-form-urlencoded;charset=utf-8 請求體
當咱們使用表單上傳文件時,必須讓<form>表單的 enctype 等於multipart/form-data。web
POST http://www.example.com HTTP/1.1 Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA ------WebKitFormBoundaryrGKCBY7qhFd3TrwA Content-Disposition: form-data; name="user" yuan ------WebKitFormBoundaryrGKCBY7qhFd3TrwA Content-Disposition: form-data; name="file"; filename="chrome.png" Content-Type: image/png PNG ... content of chrome.png ... ------WebKitFormBoundaryrGKCBY7qhFd3TrwA--
這個例子稍微複雜點。首先生成了一個 boundary 用於分割不一樣的字段,爲了不與正文內容重複,boundary 很長很複雜。而後 Content-Type 裏指明瞭數據是以 multipart/form-data 來編碼,本次請求的 boundary 是什麼內容。消息主體裏按照字段個數又分爲多個結構相似的部分,每部分都是以--boundary 開始,緊接着是內容描述信息,而後回車,最後是字段具體內容(文本或二進制)。若是傳輸的是文件,還要包含文件名和文件類型信息。消息主體最後以--boundary--表示結束。ajax
這種方式通常用於上傳文件,各大服務端語言也有很好的支持。chrome
這兩種POST 提交的方式,都是瀏覽器原生支持的,並且先階段標準中原生<form>表單也只支持這兩種方式(經過<form>元素的 enctype 屬性指定,默認爲 application/x-www-form-urlencoded)。隨着愈來愈多的web站點尤爲是 WebApp,所有使用 Ajax 進行數據交互以後,咱們徹底能夠定義新的數據提交方式,給開發帶來更多便利。django
application/json是另一種請求頭,不過更多的是做爲響應頭,由於 json 格式的數據時通用數據格式。不過目前也用來做爲請求頭,用來告訴服務器端主體是序列化後的 json 字符串。因爲 json 規範的流行,除了低版本的 IE 以外的各大瀏覽器都原生支持 json.stringfy,服務器端語言也都有處理 json數據的函數,使用 json 不會遇到什麼麻煩。json
json 格式支持比鍵值對複雜的多的結構化數據,這點對數據傳輸頗有用。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="" method="post" enctype="multipart/form-data"> <p>用戶名:<input type="text" name="name"></p> <input type="file" name="myfile"> {# <input type="file" name="myfile2">#} <input type="submit" value="提交"> </form> </body> </html>
class UploadFile(View): def get(self, request): return render(request, 'upload_file.html') def post(self, request): file = request.FILES.get('myfile') # print(file['file']) from django.core.files.uploadedfile import InMemoryUploadedFile print(time.time()) filename = str(time.time()).split('.')[0] + file.name with open(filename, 'wb') as f: for line in file: f.write(line) return HttpResponse('上傳成功')
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>uploadfile</title> <script src="/static/jquery-3.3.1.js"></script> </head> <body> <p>用戶名:<input type="text" id="name"></p> <p>選擇文件:<input type="file" id="my_file"></p> <button id="btn">上傳</button><span id="msg"></span> </body> <script> $('#btn').click(function () { var myfile = $('#my_file')[0].files[0]; var formdata = new FormData(); formdata.append('name', $('#name').val()); formdata.append('myfile', myfile); $.ajax({ url:'/uploadfile/', type:'post', processData:false, // 告訴 jQuery 不要處理髮送的數據 contentType:false, // 告訴 jQuery 不要設置 Content-Type 請求頭 data:formdata, success:function (data) { console.log(data); $('#msg').text(data) } }) }) </script> </html>
MEDIA_PATH = '/Users/jingxing/Django/homework/paging/media' def uploadfile(request): if request.method == 'GET': return render(request, 'uploadfile.html') else: myfile = request.FILES.get('myfile') print(myfile) filepath = os.path.join(MEDIA_PATH, myfile.name[32:-3]+'jpg') with open(filepath, 'wb') as f: for line in myfile: f.write(line) FileInfo.objects.create(name=request.POST.get('name'), filepath=filepath) return HttpResponse('上傳成功')
$('#submit1').click(function () { postdata={name1:$("#name").val(),pwd2:$("#pwd").val()} $.ajax({ url:'/loginjson/', type:'post', // 指定提交的編碼格式是json格式, contentType:'application/json', data:JSON.stringify(postdata), // data:postdata, // data:'123', success:function (data) { console.log(data) } }) })
def loginjson(request): dic={'status':100,'msg':None} if request.method=='POST': print(request.POST) print(request.GET) print(request.body) xx=request.body.decode('utf-8') # re是個字典{"name1":"lqz","pwd2":"123"} re=json.loads(xx) request.POST=11 print(request.POST) # # # name=re.get('name1') # pwd=re.get('pwd2') # print(name) # print(pwd) return HttpResponse('ok')
$('#submit').click(function () { $.ajax({ url:'/login/', type:'post', data:{name1:$("#name").val(),pwd2:$("#pwd").val()}, success:function (data) { //後臺用JsonResponse返回數據 //data 就會被轉成字典 console.log(data) console.log(typeof data) //JSON.parse(data) 把字符串類型轉成字典 data=JSON.parse(data) {#JSON.stringify()#} console.log(typeof dat1) if(data.status == 100){ //成功,跳轉到指定頁面 //location.href=地址,前端就會跳轉到指定的url alert(data.msg) //$("#error").text(data.msg+'正在跳轉') //location.href=data.url }else{ $("#error").text(data.msg) } } }) })
def login(request): dic={'status':100,'msg':None} if request.method == 'GET': return render(request, 'login.html') # if request.is_ajax(): if request.method=='POST': name=request.POST.get('name1') pwd=request.POST.get('pwd2') if name=='lqz' and pwd=='123': dic['msg'] = '登錄成功' # 想讓前端跳轉 # dic['url']='http://www.baidu.com' dic['url']='/test/' else: # 返回json格式字符串 dic['status']=101 dic['msg']='用戶名或密碼錯誤' # return JsonResponse(dic) return HttpResponse(json.dumps(dic))
from django.core import serializers def test(request): book_list = Book.objects.all() ret = serializers.serialize('json', book_list) return HttpResponse(ret)