zoukankan      html  css  js  c++  java
  • ajax

    向后台传输数据有两种方式1、form 提交后会刷新页面 2、ajax 提交数据后不会刷新页面

    ajax是XMLHttPRequest对象。使用ajax分为3种情况,1、手动使用  2、jQuery方式使用  3、伪ajax

    1、当遇到需求,不使用jQuery方式用ajax向后台发送数据。

    <a href="#" onclick="func()">点击</a>
        function func() {
            var xhr = new XMLHttpRequest();//创建XMLHttpRequest对象
            xhr.onreadystatechange = function(){
                if(xhr.readyState == 4){
                    console.log(xhr.responseText);//xhr.responseText保存着服务端返回来的信息
                }
            };//以XMLHttpRequest对象向后台发送数据执行的回调函数,某些状态更改会触发执行。
            //xhr.readyState取值有0-4
            xhr.open("GET", "/ajax_2?p=123");
            xhr.send(null);
        }
    def ajax_2(request):
        print(request.POST)
        print(request.GET)
        return HttpResponse("ok")

    后台没有对接收到的数据进行处理,只是打印接收到的数据。

    上述代码的步骤为:1、创建 XMLHttpRequest对象,2、根据该对象设置回调函数,3、以什么方式,向哪个url创建连接,4、发送数据。回调函数中,xhr的状态改变就会触发回调函数的执行,其状态保存在xhr.readyState中,其详细的状态有

    0——未初始化,尚未调用open方法

    1——启动,调用了open()方法,还未调用send()方法。

    2——发送,已经调用了send()方法,还未接收到响应。

    3——接收,已经接收到部分响应数据。

    4——完成,已经接收到全部响应数据。

    发送get请求和post请求不一样,发送post请求需要设置发送的请求头。

    request请求有请求头和请求体。数据发送是在request.body中,然后提取到request.GET;request.POST中,采用该方式发送数据时,请求头没有设置成Django能够识别的形式,因此需要将请求头设置成django能够识别的形式。

    <a href="#" onclick="func_1()">点击</a>
        function func_1() {
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function(){
                if(xhr.readyState == 4){
                    console.log(xhr.responseText);
                }
            };
            xhr.open("POST", "/ajax_2/");
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8')//设置请求头,Django中固定这种设置,还可以进行其他
    //的设置,这样设置Django能够解析
            xhr.send("p=456");
        }
    def ajax_2(request):
        print(request.POST)
        print(request.GET)
        return HttpResponse("ok")

     2、伪ajax

    方法:采用iframe标签和form表单一起合用完成向后台发送数据而又不刷新页面。

    该方法是兼容性最好的一种方式。

    认识iframe:iframe有默认高度和宽度,在页面上显示类似于文本框textarea,有src属性,通过src属性发送请求,请求发送到后台,后台处理后将处理结果返回显示到iframe自己的内容区域中,外面的大的页面不刷新。

    因此配合使用时需要做两点:2、在form表单上加上target="iframe标签的那么属性值"1、在iframe标签上加上name="名字"

        <iframe name="ifra_a" onload="loadData(this)" id="ifra_2"></iframe>
        <form id="fm_a" action="/file_upload_1/" method="post" enctype="multipart/form-data" target="ifra_a">
            <input type="file" name="test_file3" id="input_c" onchange="func_4()">
        </form>

    这样配合起来使用后,form提交到自己设定的路径的后台处理,后台处理后将处理的结果返回到iframe标签的内容区中。onchange表示输入框内容改变执行对应的函数。

    回调函数,怎么取iframe标签中的值?

    认识js中的this

    1、在一个具体的标签中,this带指这一个标签。

    在一个标签中有两种情况:1

     <iframe name="ifra_a" onload="loadData(this)" id="ifra_2"></iframe>

    2:

        $("#ifra_2").click(function () {
            $(this).html();
        })

    2、没有在一个具体的标签中,this带指window对象。

    func_4()实现提交form表单,相当于input标签type = 'submit'的情况。

        function func_4() {
            document.getElementById("fm_a").submit()
        }

    上述实现了将输入的文件提交到后台,通过视图函数处理请求。

    def fileUpload1(request):
        testFile = request.FILES.get("test_file3")
        file_path = os.path.join("static",testFile.name)
        data = {"status":"ok","index":file_path}
        f = open(file_path,"wb")
        for line in testFile.chunks():
            f.write(line)
        f.close()
        return HttpResponse(json.dumps(data))

    回调函数:图片预览

    function loadData(ths) {//当iframe中数据加载后执行onload对应的函数
    var data = ths.contentWindow.document.body.innerHTML; //取得body中的字符串

    var data_par = JSON.parse(data);//解析json字符串

    var ele = document.createElement("img");
    ele.src = "/"+data_par.index; //解析后的字典中的索引赋值给img对象的src属性
    $("#preview").append(ele);
    }

     ajax的三种方式实现文件的上传

    认识FormData()对象,可以看做一个特殊的字典,在其里面可以封装数据,包括文件,消息,相对于采用字典传输数据的方式,他的优势在于能够传输文件,而字典不行。

    1、jQuery

            <input type="file" name="test_file1" id="input_a">
            <a onclick="submitajax()" href="#">上传</a>
        function submitajax() {
            var testdata = new FormData();
            testdata.append("k",document.getElementById("input_a").files[0]);
            $.ajax({
                url:"/file_upload/",
                type:"POST",
                data:testdata,
                success:function (arg) {
    
                },
                processData:false,//需要加上这两个参数,表示不对数据进行处理,就是不让jquery对数据处理
                contentType:false,
            })
        }

    2、原生XMLHttpR

    <input type="file" id="input_file_c" onchange="submitajax_3()">
        function submitajax_3() {
            var data = new FormData();
            data.append("k",document.getElementById("input_file_c").files[0]);
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function () {
    
            };//回调函数
            xhr.open("POST","/file_upload_3/");
            //xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
            xhr.send(data)
        }

    采用FormData对象提交数据和采用字典方式提交还有一点不同,不需要想后台提交请求头,字典方式组织的数据需要,不然request.POST上没有数据。jquery提交会自动处理数据会加上请求头,因此需要设置processData:false,

    def fileUpload_3(request):
        print(request.POST)
        print(request.GET)
        print(request.FILES)
        testFile = request.FILES.get("k")
        file_path = os.path.join("static",testFile.name)
        data = {"status":"ok","index":file_path}
        # print(testFile.name)
        print(testFile.size)
        f = open(file_path,"wb")
        for line in testFile.chunks():
            f.write(line)
        f.close()
        return HttpResponse(json.dumps(data))

    3、iframe和from

                        <iframe style="display: none;" id="upload_iframe" name="upload_iframe"></iframe>
                        <form method="POST" action="/{{ username }}/upload-avatar/" enctype="multipart/form-data"
                              target="upload_iframe"id="upload_fm">
                            {% csrf_token %}
                            <img id="previewImg" src="/{{ user_obj.img }}"
                                 style="border-radius: 50%;height: 70px; 70px"/>
                            <div class="text">点击图片更换(<a href="#">撤销</a>)</div>
                            <input id="avatarImg" name="avatar_img" type="file" class="img-file"onchange="submit_img()"/>
                        </form>
            function submit_img() {
                document.getElementById("upload_fm").submit();
            }

     Jsonp和跨域访问

    浏览器都有同源策略;同源策略是浏览器最核心最基本的安全功能。同源是指,域名、协议、端口相同。

    同源策略分为两种:

    1、DOM同源策略

    2、XMLHTTPRequest同源策略

    不允许使用XHR对象向不同源的服务器地址发起HTTP请求

    同源策略是为了浏览器上网的安全,但是由于有了同于策略,引起了跨域访问的问题。

    JSONP跨域原理:

    script标签不会受到同源策略的影响,动态创建script标签,利用src跨域。

        <div id="div_jsonp_content"></div>
        <div href="" class="btn" onclick="func_jsonp()">点击</div>
        function func_jsonp() {
            var ele = document.createElement("script");
            ele.src = "http://127.0.0.1:8000/jsonp-test/";//跨域访问,执行路径为下面一处贴的代码
            document.head.appendChild(ele);
        document.head.removeChild(ele);   } function f_jsonp(arg) { $("#div_jsonp_content").html(arg); }

    上述第一个函数1、先创建script标签,2、利用src跨域访问3、在head中添加标签4、移除标签

    上述第二个函数,函数名和返回的字符串外层包裹相同,arg为内层字符串。

    path('jsonp-test/', views.jsonp_test),//url需要跨域的服务器
    
    def jsonp_test(request):
        return HttpResponse("f_jsonp('jsonp_test')")

     ajax有跨域访问的自动处理方式:对应的服务器返回同上。

    <div href="" class="btn" onclick="func_jsonp1()">点击</div>
        function func_jsonp1() {
            $.ajax({
                url:"http://127.0.0.1:8000/jsonp-test/",
                type:"POST",
                dataType:'JSONP',
            })
        }
        function f_jsonp(arg) {
            {#$("#div_jsonp_content").html(arg);#}
            console.log(arg)
        }

    ajax跨域指定返回的回调函数:

    <div href="" class="btn" onclick="func_jsonp1()">点击</div>
        function func_jsonp1() {
            $.ajax({
                url:"http://127.0.0.1:8000/jsonp-test/",
                type:"GET",
                dataType:'JSONP',
                jsonp:"callback",
                jsonpCallback:"ffff",
            })
        }
        function ffff(arg) {
            {#$("#div_jsonp_content").html(arg);#}
            console.log(arg)
        }

    服务器部分与先前有一些不同的地方

    不同之处在视图处理函数,如下:

    def jsonp_test(request):
        name = request.GET.get("callback")
        return HttpResponse("%s('jsonp_test')"%name)
  • 相关阅读:
    集群资源队列监控:Grafana
    1
    3月9号
    jmx
    日常笔记
    nsenter命令简介
    一天2小时
    postgresql Centos7部署
    笔记5
    1
  • 原文地址:https://www.cnblogs.com/zjsthunder/p/9754486.html
Copyright © 2011-2022 走看看