Ajax

简介

  AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术。
  AJAX = 异步 JavaScript和XML(标准通用标记语言的子集)。
  AJAX 是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

             

原生Ajax

XMLHttpRequest 是 AJAX 的基础。

A、XMLHttpRequest 对象

所有现代浏览器均支持 XMLHttpRequest 对象(IE5 和 IE6 使用 ActiveXObject)。

XMLHttpRequest 用于在后台与服务器交换数据。

1、创建XMLHttpRequest对象

    var xmlhttp;
    // Ajax的实现基本都基于XMLHttpRequest对象
    xmlhttp = new XMLHttpRequest()

2、设置回调函数

当请求被发送到服务器时,执行一些基于响应的任务。

readyState 属性存有 XMLHttpRequest 的状态信息。

属性描述
onreadystatechange 存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。
readyState

存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。

  • 0: 请求未初始化
  • 1: 服务器连接已建立
  • 2: 请求已接收
  • 3: 请求处理中
  • 4: 请求已完成,且响应已就绪
status 200: "OK"
404: 未找到页面

 每当 readyState 改变时,就会触发 onreadystatechange 事件。

    // 响应处于 onreadystatechange 事件中的就绪状态时执行的函数
    xmlhttp.onreadystatechange = function () {
        if (xmlhttp.readyState==4 && xmlhttp.status==200){
            document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
        }
    };

3、如需将请求发送到服务器,使用 XMLHttpRequest 对象的 open() 和 send() 方法

复制代码
    // GET请求 一些数据可封装在URL上面
    xmlhttp.open('GET', '/index?p=123');
    xmlhttp.send();

    // POST请求 发送的数据由send发送
    xmlhttp.open('POST', '/index/');
    // 如需要像 HTML 表单那样 POST 数据,使用 setRequestHeader() 来添加 HTTP 请求头。
    xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
    xmlhttp.send('p=321');
复制代码
方法描述
open(method,url,async)

规定请求的类型、URL 以及是否异步处理请求。

  • method:请求的类型;GET 或 POST
  • url:文件在服务器上的位置
  • async:true(异步)或 false(同步)
send(string)

将请求发送到服务器。

  • string:仅用于 POST 请求

4、服务器响应

如需获得来自服务器的响应,XMLHttpRequest 对象的 responseText 或 responseXML

在onreadystatechange执行服务器响应信息

属性描述
responseText 获得字符串形式的响应数据。
responseXML 获得 XML 形式的响应数据。

B、XMLHttpRequest 详细及DEMO

XmlHttpRequest对象的主要方法:

XmlHttpRequest对象的主要属性:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .btn{
            padding: 5px 10px;
            background-color: yellowgreen;
            color: white;
            cursor: pointer;
        }
    </style>
</head>
<body>
<h1>Index</h1>
<h2>数据发送</h2>
<h3>原生Ajax</h3>
<div>
    <a class="btn" onclick="xxoo();">原生AjaxGET</a>
    <a class="btn" onclick="ooxx();">原生AjaxPOST</a>
</div>

<script>
    function xxoo() {
        var xx = new XMLHttpRequest();  // 生成对象

        // 回调函数一般放在send上面
        xx.onreadystatechange = function () {
            // 已经接收到全部响应数据,执行以下操作
            if(xx.readyState==4){
                console.log(xx.responseText)
            }
        };
        xx.open('GET','/ajax1?p=666'); // 请求方式及对应URL
        xx.send(null)

    }

    function ooxx() {
        var oo = new XMLHttpRequest();
        oo.onreadystatechange = function () {
            if (oo.readyState==4){
                console.log(oo.responseText)
            }
        };
        oo.open('POST','/ajax1/');
        oo.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
        oo.send('p=888')
    }

</script>
基于原生Ajax的数据传输
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .btn{
            padding: 5px 10px;
            background-color: yellowgreen;
            color: white;
            cursor: pointer;
        }
    </style>
</head>
<body>
<h2>文件上传</h2>
<h3>jQuery+js</h3>
<input type="file" id='file1'>

<a class="btn" onclick="AjaxjsSubmit();">js文件上传</a>

<script>
        function AjaxjsSubmit() {
        var data = new FormData();
        data.append('file',document.getElementById('file1').files[0]);
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function () {
            if (xhr.readyState==4){
                console.log(xhr.responseText)
            }
        };
        xhr.open('POST','/ajax1/');
        xhr.send(data)
    }
</script>
基于原生Ajax的文件上传

"伪"Ajax

由于HTML标签的iframe标签具有局部加载内容的特性,所以可以使用其来伪造Ajax请求。

<!DOCTYPE html>
<html>
 
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
 
    <body>
 
        <div>
            <p>请输入要加载的地址:<span id="currentTime"></span></p>
            <p>
                <input id="url" type="text" />
                <input type="button" value="刷新" onclick="LoadPage();">
            </p>
        </div>
 
 
        <div>
            <h3>加载页面位置:</h3>
            <iframe id="iframePosition" style=" 100%;height: 500px;"></iframe>
        </div>
 
 
        <script type="text/javascript">
 
            window.onload= function(){
                var myDate = new Date();
                document.getElementById('currentTime').innerText = myDate.getTime();
 
            };
 
            function LoadPage(){
                var targetUrl =  document.getElementById('url').value;
                document.getElementById("iframePosition").src = targetUrl;
            }
 
        </script>
 
    </body>
</html>
'伪' Ajax DEMO
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .btn{
            padding: 5px 10px;
            background-color: yellowgreen;
            color: white;
            cursor: pointer;
        }
    </style>
</head>
<body>
<h3>Form+Iframe</h3>
<iframe name='ifra' id='im' style=" 800px"></iframe>
<form action="/ajax1/" id='fm' method="post" target="ifra">
    <input type="text" id='phone' name='num' value="123456789">
    <a class="btn" onclick="xoxo();">提交</a>
</form>

<script>
    function xoxo() {
        document.getElementById('fm').submit();
        document.getElementById('im').onload = iframeload;
    }
    // 获取iframe内的数据
    function iframeload() {
        var content = this.contentWindow.document.body.innerHTML;
        var obj = JSON.parse(content);
        if (obj.status){
            alert(obj.msg)
        }
    }

</script>
</body>
</html>
Form+Iframe - 数据传输
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .btn{
            padding: 5px 10px;
            background-color: yellowgreen;
            color: white;
            cursor: pointer;
        }
    </style>
</head>
<body>
<h3>Form+Iframe文件上传</h3>

<iframe name='ifra1' id='im1' style="display: none"></iframe>
<form action="/ajax1/" id='fm1' method="POST" target="ifra1" enctype="multipart/form-data">
    <input type="file" name="uploadfile">
    <a class="btn" onclick="FormFileSubmit();">Form+Iframe文件上传</a>
</form>
    function FormFileSubmit() {
        document.getElementById('fm1').submit();
        document.getElementById('im1').onload = iframefileload;
    }
    
    function iframefileload() {
        var content = this.contentWindow.document.body.innerHTML;
        var obj = JSON.parse(content);
        if (obj.status){
            alert(obj.msg)
        }
    }

</script>
</body>
</html>
Form+Iframe - 文件上传

jQuery Ajax

jQuery一贯秉承写更少、做更多的原则,依旧封装了Ajax的API,将复杂的功能做了上层封装,其本质依旧是XMLHttpRequest 或 ActiveXObject

            jQuery.get(...)
                所有参数:
                     url: 待载入页面的URL地址
                    data: 待发送 Key/value 参数。
                 success: 载入成功时回调函数。
                dataType: 返回内容格式,xml, json,  script, text, html


            jQuery.post(...)
                所有参数:
                     url: 待载入页面的URL地址
                    data: 待发送 Key/value 参数
                 success: 载入成功时回调函数
                dataType: 返回内容格式,xml, json,  script, text, html


            jQuery.getJSON(...)
                所有参数:
                     url: 待载入页面的URL地址
                    data: 待发送 Key/value 参数。
                 success: 载入成功时回调函数。


            jQuery.getScript(...)
                所有参数:
                     url: 待载入页面的URL地址
                    data: 待发送 Key/value 参数。
                 success: 载入成功时回调函数。


            jQuery.ajax(...)

                部分参数:

                        url:请求地址
                       type:请求方式,GET、POST(1.9.0之后用method)
                    headers:请求头
                       data:要发送的数据
                contentType:即将发送信息至服务器的内容编码类型(默认: "application/x-www-form-urlencoded; charset=UTF-8")
                      async:是否异步
                    timeout:设置请求超时时间(毫秒)

                 beforeSend:发送请求前执行的函数(全局)
                   complete:完成之后执行的回调函数(全局)
                    success:成功之后执行的回调函数(全局)
                      error:失败之后执行的回调函数(全局)
                

                    accepts:通过请求头发送给服务器,告诉服务器当前客户端课接受的数据类型
                   dataType:将服务器端返回的数据转换成指定类型
                                   "xml": 将服务器端返回的内容转换成xml格式
                                  "text": 将服务器端返回的内容转换成普通文本格式
                                  "html": 将服务器端返回的内容转换成普通文本格式,在插入DOM中时,如果包含JavaScript标签,则会尝试去执行。
                                "script": 尝试将返回值当作JavaScript去执行,然后再将服务器端返回的内容转换成普通文本格式
                                  "json": 将服务器端返回的内容转换成相应的JavaScript对象
                                 "jsonp": JSONP 格式
                                          使用 JSONP 形式调用函数时,如 "myurl?callback=?" jQuery 将自动替换 ? 为正确的函数名,以执行回调函数

                                  如果不指定,jQuery 将自动根据HTTP包MIME信息返回相应类型(an XML MIME type will yield XML, in 1.4 JSON will yield a JavaScript object, in 1.4 script will execute the script, and anything else will be returned as a string

                 converters: 转换器,将服务器端的内容根据指定的dataType转换类型,并传值给success回调函数
                         $.ajax({
                              accepts: {
                                mycustomtype: 'application/x-some-custom-type'
                              },
                              
                              // Expect a `mycustomtype` back from server
                              dataType: 'mycustomtype'

                              // Instructions for how to deserialize a `mycustomtype`
                              converters: {
                                'text mycustomtype': function(result) {
                                  // Do Stuff
                                  return newresult;
                                }
                              },
                            });
jQuery Ajax方法列表
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .btn{
            display: inline-block;
            padding: 5px 10px;
            background-color: coral;
            color: white;
        }
    </style>
</head>
<body>
    <h1>jQuery Ajax</h1>
    <h3>GET请求</h3>
    <div>
        <a class="btn" onclick="AjaxSubmit1();">点我</a>
    </div>
    <h3>POST请求</h3>
    <div>
        <a class="btn" onclick="AjaxSubmit3();">点我</a>
    </div>
    <script>
        function  AjaxSubmit1() {
            $.ajax({
                url: '/ajax1.html',
                type:'GET',
                data: {'p':123},
                success:function (arg) {

                }
            })
        }


        function  AjaxSubmit3() {
            $.ajax({
                url: '/ajax1.html',
                type:'POST',
                data: {'p':123},
                success:function (arg) {

                }
            })
        }
    </script>
</body>
基于jQuery Ajax - 数据传输
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .btn{
            padding: 5px 10px;
            background-color: yellowgreen;
            color: white;
            cursor: pointer;
        }
    </style>
</head>
<body>
<input type="file" id='file1'>
<a class="btn" onclick="AjaxjQsubmit();">jQuery文件上传</a>
{% load staticfiles %}
<script src="{% static 'jquery-3.1.1.js' %}"></script>
<script>
    function AjaxjQsubmit() {
        var data = new FormData();
        console.log(document.getElementById('file1').files[0]);
        data.append('file',document.getElementById('file1').files[0]);
        $.ajax({
            url: '/ajax1/',
            type: 'POST',
            data: data,
            success: function (arg) {
                console.log(arg)
            },
            processData: false,
            contentType: false
        })
    }
</script>
</body>
</html>
基于jQuery Ajax - 文件上传

注:JQueryAjax上传数组需要加一条参数 traditional: true

跨域Ajax

由于浏览器存在同源策略机制,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性。

特别的:由于同源策略是浏览器的限制,所以请求的发送和响应是可以进行,只不过浏览器不接受罢了。

浏览器同源策略并不是对所有的请求均制约:

  • 制约: XmlHttpRequest
  • 不叼: img、iframe、script等具有src属性的标签

跨域,跨域名访问,如:http://www.c1.com 域名向 http://www.c2.com域名发送请求。

A,JSONP实现跨域请求

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

    <p><input type="button" onclick="Jsonp1();"  value='提交1'/></p>
    <p><input type="button" onclick="Jsonp2();" value='提交2'/></p>

    <script type="text/javascript" src="jquery-1.12.4.js"></script>
    <script>
        function func(arg) {
            // func 为请求传过来的函数名 func([1,2,3]);
            console.log(arg)
        }

        function Jsonp1(){
            // JSONP 的本质
            var tag = document.createElement('script');
            tag.src = "http://nick.com:8001/index";
            document.head.appendChild(tag);
            document.head.removeChild(tag);
        }

        function Jsonp2(){
            $.ajax({
                url: "http://nick.com:8001/index",
                type: 'GET',
                dataType: 'JSONP',
                jsconCallBack: "func"   // 执行func函数
            })
        }

    </script>
</body>
</html>
JsonP实现机制
// 请求的地址返回值

    def get(self, *args, **kwargs):
        self.write('func([1,2,3]);')
请求地址返回值

B,CORS

原文地址:https://www.cnblogs.com/zhangliang91/p/10547597.html