Django_Ajax_

一、Ajax准备知识:json

1. 
Python序列化
//字符串 = json.dumps(对象) 对象->字符串
//对象 = json.loads(字符串) 字符串->对象

JavaScript:
//字符串 = JSON.stringify(对象) 对象->字符串
//对象 = JSON.parse(字符串) 字符串->对象

//应用场景:
//数据传输时,
//发送:字符串
//接收:字符串 -> 对象

1、js支持单引号,也支持双引号,也可以没有引号

//在js中吧{}这样的类型叫做对象,js中没有字典一说
data = {
    'name':'haiyan',
    "name":"haiyan",
     name:"haiyan"        
}   //js对象默认会把自己的键当成字符串处理,所以可以加引号也可以不加

2、json的格式

1、json只认双引号的
2、json一定是一个字符串

3.合格的json对象:

["one", "two", "three"]

{ "one": 1, "two": 2, "three": 3 }

{"names": ["张三", "李四"] }

[ { "name": "张三"}, {"name": "李四"} ]
View Code

4.不合格的json对象

{ name: "张三", 'age': 32 }                     // 属性名必须使用双引号

[32, 64, 128, 0xFFF] // 不能使用十六进制值

{ "name": "张三", "age": undefined }            // 不能使用undefined

{ "name": "张三",
  "birthday": new Date('Fri, 26 Aug 2011 07:13:10 GMT'),
  "getName":  function() {return this.name;}    // 不能使用函数和日期对象
}
View Code

5. python中的序列化/反序列化

import json
i = 10
s = "dsfdsf"
l = [11,22,33]
dic = {"name":"haiyna","age":22}
b = True
# #吧基本数据类型转换成字符串的形式
print(json.dumps(i),type(json.dumps(i)))   #10 <class 'str'>
print(json.dumps(s),type(json.dumps(s)))   #"dsfdsf" <class 'str'>
print(json.dumps(l),type(json.dumps(l)))   #[11, 22, 33] <class 'str'>
print(json.dumps(dic),type(json.dumps(dic)))  #{"name": "haiyna", "age": 22} <class 'str'>
print(json.dumps(b),type(json.dumps(b)))  #true <class 'str'>



# ===============json反序列化=============
d = {"a":1,"b":"fdgfd"}
data = json.dumps(d)
print(data,type(data))
f = open("a.txt","w")
f.write(data)   #注意这会写进去的字符串时双引号的格式
f.close()

# ===============json序列化=============
f = open("a.txt","r")
datat = f.read()
print(datat,type(datat))   #{"a": 1, "b": "fdgfd"} <class 'str'>
data = json.loads(datat)
print(data,type(data))  #{'a': 1, 'b': 'fdgfd'} <class 'dict'>
View Code

6.jS中的序列化(stringify)与反序列化(parse)

<script>
//===========js中的json序列化===========
s = '{"name":1}';    
var data = JSON.parse(s);
console.log(data);
console.log(typeof data);   //object
//===========js中的json的反序列化=======
s2={'name':'yuan'};
console.log(JSON.stringify(s2),typeof JSON.stringify(s2))  //string
</script>
View Code

二 Ajax

1 初始Ajax

我们以前知道的前端向后端发送数据的方式有: 1. GET:地址栏、a标签、Form表单     2. POST:Form表单

ajax:也是前端向后端发送数据的一种方式

AJAXAsynchronous Javascript And XML)翻译成中文就是异步JavascriptXML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。

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

Ajax的特点:

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

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

js的局部刷新:

对于WEB应用程序:用户浏览器发送请求,服务器接收并处理请求,然后返回结果,往往返回就是字符串(HTML),浏览器将字符串(HTML)渲染并显示浏览器上。

1、传统的Web应用

一个简单操作需要重新加载全局数据

2、AJAX

AJAX,Asynchronous JavaScript and XML (异步的JavaScript和XML),一种创建交互式网页应用的网页开发技术方案。

  • 异步的JavaScript:
    使用 【JavaScript语言】 以及 相关【浏览器提供类库】 的功能向服务端发送请求,当服务端处理完请求之后,【自动执行某个JavaScript的回调函数】。
    PS:以上请求和响应的整个过程是【偷偷】进行的,页面上无任何感知。
  • XML
    XML是一种标记语言,是Ajax在和后台交互时传输数据的格式之一

利用AJAX可以做:
1、注册时,输入用户名自动检测用户是否已经存在。
2、登陆时,提示用户名密码错误
3、删除数据行时,将行ID发送到后台,后台在数据库中删除,数据库删除成功后,在页面DOM中将数据行也删除。(博客园)

2 Ajax参数

View Code

3 AJax大全

 

 jqurey 提供的 ajax

1 jqurey
function submitJsonp1() {
            $.ajax({
                url: '/ajax3.html',
                type: 'GET',
                data: {nid:2},
                success:function (arg) {
                    $('#content').html(arg);
                }
            })
        }
View Code

原生AJAX

Ajax主要就是使用 【XmlHttpRequest】对象来完成请求的操作,该对象在主流浏览器中均存在(除早起的IE),Ajax首次出现IE5.5中存在(ActiveX控件)。

1、XmlHttpRequest对象介绍

XmlHttpRequest对象的主要方法:

a. void open(String method,String url,Boolen async)
   用于创建请求
    
   参数:
       method: 请求方式(字符串类型),如:POST、GET、DELETE...
       url:    要请求的地址(字符串类型)
       async:  是否异步(布尔类型)
 
b. void send(String body)
    用于发送请求
 
    参数:
        body: 要发送的数据(字符串类型)
 
c. void setRequestHeader(String header,String value)
    用于设置请求头
 
    参数:
        header: 请求头的key(字符串类型)
        vlaue:  请求头的value(字符串类型)
 
d. String getAllResponseHeaders()
    获取所有响应头
 
    返回值:
        响应头数据(字符串类型)
 
e. String getResponseHeader(String header)
    获取响应头中指定header的值
 
    参数:
        header: 响应头的key(字符串类型)
 
    返回值:
        响应头中指定的header对应的值
 
f. void abort()
 
    终止请求
View Code

XmlHttpRequest对象的主要属性

a. Number readyState
   状态值(整数)
 
   详细:
      0-未初始化,尚未调用open()方法;
      1-启动,调用了open()方法,未调用send()方法;
      2-发送,已经调用了send()方法,未接收到响应;
      3-接收,已经接收到部分响应数据;
      4-完成,已经接收到全部响应数据;
 
b. Function onreadystatechange
   当readyState的值改变时自动触发执行其对应的函数(回调函数)
 
c. String responseText
   服务器返回的数据(字符串类型)
 
d. XmlDocument responseXML
   服务器返回的数据(Xml对象)
 
e. Number states
   状态码(整数),如:200404...
 
f. String statesText
   状态文本(字符串),如:OK、NotFound...
View Code
    function AjaxSubmit2(){
        var xhr=new XMLHttpRequest();//创建对象

        xhr.onreadystatechange=function(){
            if (xhr.readyState==4){
                console.log(xhr.responseText) //xhr.responseText表示返回的文本信息
            }
        } ; //当某一个状态更改的时候执行; xhr.readyState有很多状态, 如果==4表示接受完毕

        xhr.open('GET','/ajax/?p=123'); //以什么方式发,url get请求发加在url中
        xhr.send(null) //表示要发送,null表示什么都不发
    }
GET方式的原生Ajax
    function AjaxSubmit4(){
        var xhr=new XMLHttpRequest();//创建对象

        xhr.onreadystatechange=function(){
            if (xhr.readyState==4){
                console.log(xhr.responseText)
            }
        } ; //当某一个状态更改的时候执行


        xhr.open('POST','/ajax/');
        xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset-UTF-8');// 第一个k 第二个value
        xhr.send('p=123')
    }
POST方式原生Ajax

“伪”AJAX

1学习 iframe

//<div>学习iframe</div>
//    <iframe style=" height: 500px ;width: 500px " src="http://www.autohome.com.cn"></iframe>
// iframe 通道  不刷新网页

2 基于 iframe 和from 表单 进行 伪Ajax

 

<div>
    <h5>from+frame</h5>

    <iframe id="frame" name="frames" ></iframe>
    <form id='fm' action="/ajax/" method="post" target="frames">
//必须设置 target == frames (iframe,那么的值)

        <input type="text" name="1111" >
        <a class="btn" onclick="AjaxSubmit5()">点我a </a>//通过 onclic提交, 和下面的一样,不过可以执行函数

        #<input type="submit" value="提交"> //直接提交
    </form>

</div>

    //如果在表单上绑定onload this需要传递,否则等于widow,    如果在script不用传 this等于当前标签
    function AjaxSubmit5() {
        $('#fm').submit();
        document.getElementById('frame').onload=function () {
           {#var content=this.contentWindow.document.body.innerHTML#}

            console.log($(this).contents().find('body').html())
            
        }
    }
//给iframe 绑定.onload , 相当于回调函数

3 文件上传 jquery和原生      基于Fromdata 完成文件上传

<div>
    <h5>juaery文件上传</h5>
    <input type="file" id="img">
    <a class="btn" onclick="AjaxSubmit6()">上传文件formData</a>
    <a class="btn" onclick="AjaxSubmit7()">上传文件httpresformData</a>

</div>

    function AjaxSubmit6(){

        var data=new FormData();  // 创建一个 data对象
        data.append('k1','v1');
        data.append('k2','v1');
        data.append('k3',document.getElementById('img').files[0]);
//获取上传文件的内容, 标准用法
        $.ajax({
            url:'/ajax/',
            type:'POST',
            data:data,
            success:function (arg) {

                console.log(arg)


            },
            processData:false,
            contentType:false
            // 用FormData(); 必须加这两个参数;  表示不让jquery做特殊处理,直接发过去
        })
    }

    function AjaxSubmit7(){
        var data=new FormData();
        data.append('k1','v1');
        data.append('k2','v1');
      data.append('k3',document.getElementById('img').files[0]);
        var xhr=new XMLHttpRequest();//创建对象

        xhr.onreadystatechange=function(){
            if (xhr.readyState==4){
                console.log(xhr.responseText)
            }
        } ; //当某一个状态更改的时候执行

        xhr.open('POST','/ajax/'); //以什么方式发,url
        xhr.send(data)
    }
    
View Code

4 from+iframe+文件上传】

<div>
    <h5>from+iframe+文件上传</h5>

    <iframe style="display: none" id="frame1" name="frames1" ></iframe>
    <form id='fm1' action="/ajax/" method="post" target="frames1" enctype="multipart/form-data" >
        <input type="text" name="k1" >
        <input type="text" name="k2" >
        <input type="file" name="k3" >
        <a class="btn" onclick="AjaxSubmit8()">点我a </a>
    </form>

</div>

    function AjaxSubmit8() {
        $('#fm1').submit();
        document.getElementById('frame1').onload=function () {
           {#var 
          content=this.contentWindow.document.body.innerHTML#}

           var content= $(this).contents().find('body').html()

            var obj=JSON.parse(content)

            console.log(obj)

        }
    }
from+iframe+文件上传

5 from+iframe+文件上传+ 不加提交,可以预览, 高潮

可以用来点击头像直接更改

function uploadFile() {

         $('#fm1').submit();
//先提交
         document.getElementById('frame1').onload=reloadiframe
     }
//给 ifream绑定回调函数
     function reloadiframe () {

           var content=this.contentWindow.document.body.innerHTML;
           var obj=JSON.parse(content);
           console.log(obj.data);
//拿到回调字符串, JSON一下变成对象
           var tag=document.createElement('img');
           tag.src='/'+ obj.data ;
           $("#preview").empty().append(tag);

// 创建标签 img   src=静态文件路径

//  #preview标签 先删除标签 再添加tag


            {#console.log($(this).contents().find('body').html())#}

         }
script
<div id="id1">
    <h5>from+iframe+文件上传</h5>

    <iframe id="frame1" name="frames1"  style="display: none"></iframe>
//设置自己的dispaly=none隐藏
    <form id='fm1' action="/uploadimg/" method="post" target="frames1" enctype="multipart/form-data" >
        <input type="file" name="k3" onchange="uploadFile()">
    </form>
//input 标签绑定 onchange事件 表示状态改变的时候执行
</div>
<h3>预览</h3>
<div id="preview">
// 用来添加img标签的
</div>
html
def uploadimg(req):
    nid=str(uuid.uuid4())
//创建一个uuid
    ret={'status':True,'message':None,'data':None}
    obj=req.FILES.get('k3')
    # 获取input name=k3 的值 (图片对象)

    file_path=os.path.join('static',nid+obj.name)
//路径
    f=open(file_path,'wb')
    for line in obj.chunks():
        f.write(line)
    f.close()
    ret['data']=file_path

    return HttpResponse(json.dumps(ret))
View

 

 

三 cookie和session的介绍

1

cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞生。

cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上cookie,这样服务器就能通过cookie的内容来判断这个是“谁”了。

cookie虽然在一定程度上解决了“保持状态”的需求,但是由于cookie本身最大支持4096字节,以及cookie本身保存在客户端,可能被拦截或窃取,因此就需要有一种新的东西,它能支持更多的字节,并且他保存在服务器,有较高的安全性。这就是session。

问题来了,基于http协议的无状态特征,服务器根本就不知道访问者是“谁”。那么上述的cookie就起到桥接的作用。

我们可以给每个客户端的cookie分配一个唯一的id,这样用户在访问时,通过cookie,服务器就知道来的人是“谁”。然后我们再根据不同的cookie的id,在服务器上保存一段时间的私密资料,如“账号密码”等等。

总结而言:cookie弥补了http无状态的不足,让服务器知道来的人是“谁”;但是cookie以文本的形式保存在本地,自身安全性较差;所以我们就通过cookie识别不同的用户,对应的在session里保存私密的信息以及超过4096字节的文本。

另外,上述所说的cookie和session其实是共通性的东西,不限于语言和框架

 1 cookie的简单使用

1、获取Cookie

request.COOKIES.get("islogin",None)  #如果有就获取,没有就默认为none

2、设置Cookie

 obj = redirect("/index/")
  obj.set_cookie("islogin",True)  #设置cookie值,注意这里的参数,一个是键,一个是值
  obj.set_cookie("haiyan","344",20)  #20代表过期时间
  obj.set_cookie("username", username)

3、删除Cookie

obj.delete_cookie("cookie_key",path="/",domain=name)
def login(req):
    print("cook",req.COOKIES)
    print("seek",req.session)
    if req.method=="POST":
        name=req.POST.get("user")
        pwd=req.POST.get("pwd")
        if name=="yuan" and pwd=="123":
           # ret= redirect("/index/")
           # ret.set_cookie("username",name)
return  render(req,"login.html")
def index(req):
     if req.COOKIES.get("username",None): //只要有username说明登陆过了
    name =req.COOKIES.get("username",None)
    return render(req, "index.html", locals())
    else:
        return redirect("/login/")

2 session的简单使用

1、基本操作(需要掌握的)

1、设置session值
    request.session["session_name"]="admin"
2、获取session值
    session_name = request.session("session_name")
3、删除session值
    del request.session["session_name"]  删除一组键值对
    request.session.flush()   删除一条记录
4、检测是否操作session值
    if "session_name"  is request.session:

2

def login(req):
    print("cook",req.COOKIES)
    print("seek",req.session)
    if req.method=="POST":
        name=req.POST.get("user")
        pwd=req.POST.get("pwd")
        if name=="yuan" and pwd=="123":
           req.session["is_login"]=True
           req.session["user"] = name
           # req.session.set_expiry(5)
           return redirect("/index/")
return  render(req,"login.html")


def index(req):
    if req.session.get("is_login",None):
        name=req.session.get("user",None)
        return render(req, "index.html", locals())
    else:
        return redirect("/login/")

3、流程解析图

由于cookie会把所有的信息都保存在客户端,也就是浏览器上,这样会导致不安全,所以引用了session,但是只是单单的session也不好用,必须session和cookie配合这去用。

session会把信息保存在服务端。

 四 文件上传

1 from

class UplodaFrom(forms.Form):
    user=fields.CharField()
    img=fields.FileField()//对应上传


def uploda(requset):
    if requset.method=='GET':
        return  render(requset,"uploda.html")

    else:
        obj=UplodaFrom(requset.POST,requset.FILES)

        if obj.is_valid():
            user=obj.cleaned_data['user']
            img=obj.cleaned_data['img']
            print(requset.POST)
            print(requset.FILES)
            with open(img.name,'wb') as f :
                for line in img.chunks():
                    f.write(line)
            return HttpResponse('ok')
//img.name, 名字     img.size 大小
函数
<body>
<form action="uploda" method="post" enctype="multipart/form-data">
    {% csrf_token%}
    <input type="text" name="user">
    <div style="position: relative">
       <a style="border: burlywood 1px groove  ; border-radius: 20%; background-color: cornflowerblue ; color: white;">上传</a>
       <input type="file" name="img" style="opacity:0.1; position: absolute; top: 0 ; left: 0">
    </div>
//设置fuqin relative   一个上传标签 一个选择文件input标签 让上传标签的覆盖选择文件标签,  这样画面比较好看  只会显示上传
    <input type="submit" value="提交">
</form>
</body>
html

 

 







posted @ 2019-01-13 03:16  new边城  阅读(60)  评论(0)    收藏  举报