zoukankan      html  css  js  c++  java
  • Python学习笔记Day24

    初识Ajax

    验证输入信息
    悄悄地提交,不刷新页面

    $('i1').click(function(){
        $.ajax({
            url: '/host',
            type: "POST",
            data: {'k1': 123,'k2': "root",'k4': JSON.stringfy({'k1': 'v'})}, // 要提交的数据
            // .stringfy() 将字典序列化成字符串
            // traditional:true                 // 使发送的data中可以接收列表数据'k3':[1,2,3]
            // data:$('#add_form').serialize(),  // 自动将form表单中的数据打包发送,上传文件看下面
    
            dataType:'JSON',                 // 自动将接收到的data反序列化成obj返回
            success: function(data){        // 此处data为接收到返回的httpRes信息,可传obj
                // 服务器返回信息后自动触发
                // data是服务器端返回的字符串, 如果用dataType:'JSON', 传的参数是obj对象
                // var obj = JSON.parse(data);     // json将字符串反序列化成字典  #.stringfy()序列化
                if (obj.status){
                    location.reload();          // 刷新          
                    location.href = "某个地址"  // 跳转
                }else{
                    $('#error_msg').text(obj.error)         // 将收到的错误信息传给error_msg标签
                }
            },
            error:function(){
                ...
                //后台未接收到请求或未返回数据等未知错误
            }
        })
    })
    
    • 其他写法:(不推荐)

        $.get(url='',data='',success='function(){}')
        $.post(url='',data='',success='function(){}')
      
    • 建议:永远让服务器端返回一个字典

        ret={'status':True,'error':None,'data':None}
        return HttpResponse(json.dumps(ret))    #json将字典序列化成字符串
      
    • ajax返回数据推荐用HttpResponse

        提交 -> url -> 函数或类中的方法
                    HttpResponse('{}')
                    render(request, 'index.html', {'name': 'v1'})
                    "<h1>{{ name }}</h1>" -->> "<h1>v1</h1>"  只能返回字符串给用户    
                    不能redirect()
        用户  <<<<<  字符串
      
    • ajax只发送数据不涉及表单时,解决csrf_token

        引入cookie,在ajax中将cookie中的csrftoken添加至请求头中
        <script src="/static/jquery.cookie.js"></script>
            $.ajax({
                ...
                headers: {"X-CSRFToken": $.cookie('csrftoken')},
                ...
                })
      

    Ajax发送数据

    参考博客

    大部分采用XMLHttpRequest,但IE只支持ActiveXObject

    原生Ajax

    • 创建XMLHttpRequest或ActiveXObject对象

        function GetXHR(){
            var xhr = null;
            if(XMLHttpRequest){
                xhr = new XMLHttpRequest(); 
            }else{
                xhr = new ActiveXObject("Microsoft.XMLHTTP");
            }
            return xhr;
        }
      
    • 提交数据

        function XhrPostRequest(){
            var xhr = GetXHR();
            // 定义回调函数
            xhr.onreadystatechange = function(){
                if(xhr.readyState == 4){
                    // 已经接收到全部响应数据,执行以下操作
                    var data = xhr.responseText;
                    console.log(data);
                }
            };
            // 指定连接方式和地址----文件方式
            xhr.open('POST', "/test/", true);
            // 设置请求头,设置发送的数据类型
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
            // 发送请求
            xhr.send('n1=1;n2=2;');
        }
      
    • 接收数据

        function XhrGetRequest(){
            var xhr = GetXHR();
            // 定义回调函数
            xhr.onreadystatechange = function(){
                if(xhr.readyState == 4){
                    // 已经接收到全部响应数据,执行以下操作
                    var data = xhr.responseText;
                    console.log(data);
                }
            };
            // 指定连接方式和地址----文件方式
            xhr.open('get', "/test/", true);
            // 发送请求
            xhr.send();
        }
      

    基于jQuery的Ajax

    jQuery其实就是一个JavaScript的类库,其将复杂的功能做了上层封装,使得开发者可以在其基础上写更少的代码实现更多的功能

    jQuery 不是生产者,而是大自然搬运工。
    jQuery Ajax本质: XMLHttpRequest 或 ActiveXObject
    注:2.+版本不再支持IE9以下的浏览器

    $.ajax({
        url: '/upload_file/',
        type: 'POST',
        data: fd,
        success:function(arg,a1,a2){
            console.log(arg);
            console.log(a1);
            console.log(a2);    # a2包含一个xhr对象
        }
    })
    

    伪Ajax操作(iframe)

    由于HTML标签的iframe标签具有局部加载内容的特性,所以可以使用其来伪造Ajax请求。
    服务端返回时,触发iframe的onload事件,并将数据放在iframe的#document对象中
    也可自定义onload事件,使用$('#ifm1').contents()获取iframe内的标签

    <form action="/ajax_json/" method="POST" target="ifm1">     # target将form与iframe绑定
        <iframe id="ifm1" name="ifm1" ></iframe>
        <input type="text" name="username" />
        <input type="text" name="email" />
        <input type="submit" onclick="sumitForm();" value="Form提交"/>
    </form>
    
    function sumitForm(){
        $('#ifm1').load(function(){
            var text = $('#ifm1').contents().find('body').text();
            var obj = JSON.parse(text);
        })
    }
    

    三种方式使用的时机

    如果发送的是【普通数据】 -> jQuery,XMLHttpRequest,iframe

    如果发送的是【文件】 -> iframe,jQuery(FormData),XMLHttpRequest(FormData)

    文件上传(预览)

    上传按钮的input框本身不能直接style修改美化,只能通过relative伪覆盖添加新的标签进行美化

    上传文件三种方式:

    1. iframe

    兼容性好

    <form id="form1" action="/upload_file/" method="POST" enctype="multipart/form-data" target="ifm1">
        <iframe id="ifm1" name="ifm1" style="display: none;"></iframe>
        <input type="file" name="fafafa" onchange="changeUpalod();" />
        <input type="submit" onclick="iframeSubmit();" value="Form提交"/>
    </form>
    
    function iframeSubmit(){
        $('#ifm1').load(function(){
            var text = $('#ifm1').contents().find('body').text();
            var obj = JSON.parse(text);
            // 实现预览
            $('#preview').empty();
            var imgTag = document.createElement('img');
            imgTag.src = "/" + obj.data;
            $('#preview').append(imgTag);
        })
    }
    

    2. jQuery(FormData)

    function jqSubmit(){
        // ajax上传文件必须通过FormData对象传输数据
        var formdata = new FormData();
        
        formdata.append('username', $('#username').val());
        formdata.append('psd', $('#password').val());
        formdata.append('file', $('#file')[0].files[0]);
    
        $.ajax({
            url: '/upload_file/',
            type: 'POST',
            headers: { "X-CSRFToken": $.cookie('csrftoken') },
            data: formdata,
            processData: false,  // 不处理数据(文件上传必须)
            contentType: false,  // 不设置内容类型,按原格式传输(文件上传必须)
            success:function(arg,a1,a2){
                console.log(arg);
                console.log(a1);
                console.log(a2);
            }
        })
    }
    

    3. XMLHttpRequest(FormData)

    function xhrSubmit(){
        // $('#fafafa')[0]              // 获取input上传的文件对象
        var file_obj = document.getElementById('fafafa').files[0];  
    
        var fd = new FormData();        // 创建FormData对象
        fd.append('username','root');   // 添加普通数据,key-value
        fd.append('fafafa',file_obj);   // 添加文件对象,key-obj
    
        var xhr = new XMLHttpRequest();
        xhr.open('POST', '/upload_file/',true);
        xhr.onreadystatechange = function(){
            if(xhr.readyState == 4){
                // 接收完毕
                var obj = JSON.parse(xhr.responseText);
                console.log(obj);
            }
        };
        xhr.send(fd);
    }
    

    图片验证码 + Session

    1. GET访问页面

    -> 创建图片并返回给用户
        => 用Pillow模块创建一张图片,并在图片中写入随机字符串(封装成check_code.py模块,返回img对象和验证字符串strs)(依赖字体文件)
            img, code = creat_validate_code()
        => 将img写入内存
            stream = BytesIO()
            img.save(stream,'PNG')
        => 读取内存中的图片并显示
            data = stream.getValue()
            HttpResponse(data)
    -> session存放验证码
        => 将code写入session
            request.session['CheckCode'] = code
    

    2. POST提交数据

    -> 比对验证码
        if request.session['CheckCode'].upper() == request.POST.get('check_code').upper();
            ...
    -> 更换验证码
        绑定点击事件 onclick="changeCheckCode(this);"
        ths.src = ths.src + '?'     # 采用地址后面加?的方式,更换地址重新获取验证码
    

    JSONP - 最广泛的跨域请求方式

    (JSONP - JSON with Padding是JSON的一种“使用模式”),利用script标签的src属性实现跨域请求

    import requests
    response = request.get('http://www.baidu.com')
    response = request.post('http://www.baidu.com')
    # print(response.content)   # 字节格式的文本
    response.encoding = 'utf-8' # 指定编码
    print(response.text)        # 文本内容(经编码后的字符串)
    print(response.headers)     # 响应头
    print(response.cookies)     # 所有cookies
    
    return render(request, 'req.html',{'result': response.text})
    

    由于浏览器具有同源策略(阻止Ajax请求,但无法阻止)

    JSONP使用js巧妙实现跨域请求:

    1. 创建script标签

       var tag = document.createElement('script');
      
    2. src=远程地址

       tag.src = 'http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403';
      
    3. 将标签添加进header,随后移除

       document.head.appendChild(tag);
       document.head.removeChild(tag);
      
    4. 返回的数据必须是js格式

       必须提前写好函数才能解析返回的js代码,可将函数名用callback参数传给url
      

    JSONP只能发GET请求

    利用ajax实现JSONP请求:

    $.ajax({
            url: 'http://www.jxntv.cn/data/jmd-jxtv2.html',
            type: 'POST',
            dataType: 'jsonp',
            jsonp: 'callback',
            jsonpCallback: 'list'       # 传递函数名
        })
    原理同上
    

    还有CORS方式跨域请求,直接将域名加白名单

    编辑框

    CKEditor,UEEditor,TinyEditor,KindEditor(***)

    参考博客

    1.基本使用

    官网下载

    • 文件夹说明

        ├── asp                         -> asp示例
        ├── asp.net                     -> asp.net示例
        ├── attached                    -> 空文件夹,放置关联文件attached
        ├── examples                    -> HTML示例
        ├── jsp                         -> java示例
        ├── lang                        -> 支持语言
        ├── license.txt                 -> License
        ├── php                         -> PHP示例
        ├── plugins                     -> KindEditor内部使用的插件
        ├── themes                      -> KindEditor主题
        ├── kindeditor-all-min.js       -> 全部JS 包含插件(压缩)
        ├── kindeditor-all.js           -> 全部JS 包含插件(未压缩)
        ├── kindeditor-min.js           -> 仅KindEditor JS(压缩)
        └── kindeditor.js               -> 仅KindEditor JS(未压缩)
      
    • HTML

        <textarea name="content" id="content"></textarea>
         
        <script src="/static/jquery-1.12.4.js"></script>
        <script src="/static/plugins/kind-editor/kindeditor-all.js"></script>
        <script>
            $(function () {
                initKindEditor();
            });
         
            function initKindEditor() {
                var kind = KindEditor.create('#content', {
                     '100%',       // 文本框宽度(可以百分比或像素)
                    height: '300px',     // 文本框高度(只能像素)
                    minWidth: 200,       // 最小宽度(数字)
                    minHeight: 400      // 最小高度(数字)
                });
            }
        </script>
      
    • 详细参数

    http://kindeditor.net/docs/option.html

    2.文件上传

    • 文件上传,多文件上传,文件空间管理

    3.XSS攻击(过滤的函数或类)

    下节课说...

    使用kindeditor会隐藏原来的textarea标签,而如果该标签为required,提交时浏览器会报错

    解决办法:

    1. form表单添加novalidate属性,但会导致所有验证都不能用,不建议

    2. 取消该标签的required

    作业

    主站:

    http://127.0.0.1:8000/                  博客首页
    http://127.0.0.1:8000/zhaofan/1.html    某人的某篇博客
    

    个人博客:

    http://127.0.0.1:8000/zhaofan.html                  某人的博客
    http://127.0.0.1:8000/zhaofan/tag/python.html       某人的博客筛选
    http://127.0.0.1:8000/zhaofan/catetory/mvc.html     某人的博客筛选
    http://127.0.0.1:8000/zhaofan/date/2011-11.html     某人的博客筛选
    

    个人后台管理:

    http://127.0.0.1:8000/backend/base-info.html
    http://127.0.0.1:8000/backend/tag.html
    http://127.0.0.1:8000/backend/category.html
    http://127.0.0.1:8000/backend/article.html
    http://127.0.0.1:8000/backend/add-article.html
  • 相关阅读:
    C语言之数组中你所不在意的重要知识
    Word2007怎样从随意页開始设置页码 word07页码设置毕业论文
    天将降大任于斯人也,必先苦其心志,劳其筋骨,饿其体肤,空乏其身,行拂乱其所为,所以动心忍性,增益其所不能
    高速排序算法
    Cocos2d-x中停止播放背景音乐
    Netflix公司监控内部安全的开源项目
    Linux内核——进程管理与调度
    WebService之Soap头验证入门
    Google搜索解析
    android-sdk-windows版本号下载
  • 原文地址:https://www.cnblogs.com/JeromeLong/p/13252535.html
Copyright © 2011-2022 走看看