本篇博客介绍在 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)