Ajax

一. ajax知识点总结

1. ajax概述

对于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向后台发送请求的两种方式

 2.1 方式1:通过jQuery Ajax 

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

  • jQuery 不是生产者,而是大自然搬运工。
  • jQuery Ajax本质 XMLHttpRequest 或 ActiveXObject 

注:2.+版本不再支持IE9以下的浏览器

 <1>jQuery Ajax方法总结

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方法列表 
$.ajax({
        url: 'http//www.baidu.com',
        type: 'GET',
        data: {'k1':'v1'},
        success:function(arg){
            // arg是字符串类型
            // var obj = JSON.parse(arg)
        }
    })
$.ajax({
        url: 'http//www.baidu.com',
        type: 'GET',
        data: {'k1':'v1'},
        dataType: 'JSON',
        success:function(arg){
            // arg是对象
        }
    })
jQuery Ajax使用

 2.2 方式2:使用 【XmlHttpRequest】对象来完成请求的操作 

 方式2即使用原生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
   状态码(整数),如:200、404...
 
f. String statesText
   状态文本(字符串),如:OK、NotFound...
View Code

3. Ajax练习

   3.1 Ajax发送GET请求(jQuery Ajax和原生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>Ajax全套</h1>
    <h3>1.Ajax发送GET请求</h3>
    <div>
        <a class="btn" onclick="AjaxSubmit1();">点我</a>
        <a class="btn" onclick="AjaxSubmit2();">点我</a>
    </div>
<script src="/static/jquery-3.1.1.js"></script>
<script>
   function  AjaxSubmit1() {
            $.ajax({
                url: '/ajax1.html',
                type:'GET',
                data: {'p':123},
                success:function (arg) {
                    console.log(arg)
                }
            })
        }

        function AjaxSubmit2() {
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function () {
                if(xhr.readyState == 4){
                    // 接收完毕服务器返回的数据
                    console.log(xhr.responseText);
                }
            };
            xhr.open('GET','/ajax1.html?p=123');
            xhr.send(null);
        }

</script>
</body>
</html>
HTML
from django.shortcuts import render,HttpResponse
from django.shortcuts import redirect

def index(request):
    return render(request,'ajax_index.html')

def ajax1(request):
    ret = {'status': True, 'message': '....'}
    import json
    return HttpResponse(json.dumps(ret))
View Code

   3.2 Ajax发送POST请求(jQuery Ajax和原生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>Ajax全套</h1>
    <h3>2.Ajax发送POST请求</h3>
    <div>
        <a class="btn" onclick="AjaxSubmit3();">点我</a>
        <a class="btn" onclick="AjaxSubmit4();">点我</a>
    </div>
<script src="/static/jquery-3.1.1.js"></script>
<script>

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

                }
            })
        }

        function AjaxSubmit4() {
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function () {
                if(xhr.readyState == 4){
                    // 接收完毕服务器返回的数据
                    console.log(xhr.responseText);

                }
            };
            xhr.open('POST','/ajax1.html');
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
            //设置请求头
            xhr.send("p=456");
        }

</script>
</body>
</html>
View Code

   3.3 Ifram伪造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>Ajax全套</h1>
    <h3>3.伪Ajax发送请求</h3>
    <div>

        <h6>基于Iframe+Form表单</h6>
        <iframe id="iframe" name="ifra"></iframe>
        <form id="fm" action="/ajax1.html" method="POST" target="ifra">
            <input name="root" value="111111" />
            <a  class="btn" onclick="AjaxSubmit5()">提交</a>
        </form>

    </div>
<script src="/static/jquery-3.1.1.js"></script>
<script>

         function AjaxSubmit5() {
            document.getElementById('iframe').onload = reloadIframe;
            document.getElementById('fm').submit();
        }

        function reloadIframe() {
            // this=当前标签
            //console.log(ths);
            //console.log(ths.contentWindow);
            //用dom对象
            //console.log(ths.contentWindow.document.body.innerHTML);
            //用jquery
            //console.log($(ths).contents().find('body').html());
            var content = this.contentWindow.document.body.innerHTML;
            var obj = JSON.parse(content);
            if(obj.status){
                console.log(obj.message);
            }
        }

</script>
</body>
</html>
View Code

4. Ajax上传文件

   4.1利用formData对象封装用户提交的数据,利用jQury和原生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>Ajax全套</h1>
    <div>
        <h3>4.文件上传</h3>
    <input type="file" id="img" />
    <a class="btn" onclick="AjaxSubmit6();">上传</a>
    <a class="btn" onclick="AjaxSubmit7();">上传</a>

    </div>
<script src="/static/jquery-3.1.1.js"></script>
<script>
    function AjaxSubmit6() {
            //document.getElementById('img')[0]
            var data = new FormData();
            data.append('k1','v1');
            data.append('k2','v2');
            data.append('k3',document.getElementById('img').files[0]);

            $.ajax({
                url: '/ajax1.html',
                type: 'POST',
                data:data,
                success:function (arg) {
                    console.log(arg)
                },
                 processData: false,  // tell jQuery not to process the data
                 contentType: false  // tell jQuery not to set contentType

            })
        }

        function AjaxSubmit7() {
            var data = new FormData();
            data.append('k1','v1');
            data.append('k2','v2');
            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','/ajax1.html');
            xhr.send(data);
        }
</script>
</body>
</html>
View Code

   4.2利用伪ajax(ifram+form)上传文件

<!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>Ajax全套</h1>
    <div>
        <h3>4.文件上传</h3>
    <iframe style="display: none" id="iframe1" name="ifra1"></iframe>
    <form id="fm1" action="/ajax1.html" method="POST" enctype="multipart/form-data" target="ifra1">
        <input type="text" name="k1" />
        <input type="text" name="k2" />
        <input type="file" name="k3" />
        <a class="btn" onclick="AjaxSubmit8()">提交</a>
    </form>

    </div>
<script src="/static/jquery-3.1.1.js"></script>
<script>
   function AjaxSubmit8() {
            document.getElementById('iframe1').onload = reloadIframe1;
            document.getElementById('fm1').submit();
        }
        function reloadIframe1() {
            var content = this.contentWindow.document.body.innerHTML;
            var obj = JSON.parse(content);
            console.log(obj);
        }
</script>
</body>
</html>
View Code

   4.3上传文件练习

<!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>

    <iframe style="display: none" id="iframe1" name="ifra1"></iframe>
    <form id="fm1" action="/upload_img" method="POST" enctype="multipart/form-data" target="ifra1">
        <input type="file" name="k3" onchange="uploadFile();" />
    </form>
    <h3>预览</h3>
    <div id="preview">
    </div>
    <script src="/static/jquery-3.1.1.js"></script>
    <script>

        function uploadFile() {
            document.getElementById('iframe1').onload = reloadIframe1;
            document.getElementById('fm1').submit();
        }
        function reloadIframe1() {
            var content = this.contentWindow.document.body.innerHTML;
            var obj = JSON.parse(content);
            console.log(obj);

            var tag = document.createElement('img');
            tag.src = obj.data;
            $('#preview').empty().append(tag);
        }
    </script>
</body>
</html>
HTML
from django.shortcuts import render,HttpResponse
import json

def upload(request):
    return render(request,'ajax_upload.html')


def upload_img(request):
    import os
    import uuid
    print(request.FILES)
    nid = str(uuid.uuid4())#生成随机字符串,保证路径唯一
    ret = {'status':True,'data':None,'message':None}
    obj = request.FILES.get('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 Code

二. 跨域Ajax

1. 跨域Ajax简介

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

如果协议,端口和主机对于两个页面是相同的,则两个页面具有相同的源,否则就是不同源的。

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

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

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

2. 跨域的两种方法 

 2.1 JAONP实现跨域请求

  首先我们需要明白,在页面上直接发起一个跨域的ajax请求是不可以的,但是,在页面上引入不同域上的js脚本却是可以的,就像你可以在自己的页面上使用<img src=""> 标签来随意显示某个域上的图片一样。我们可以使用<script src="">来完成一个跨域请求,具体步骤如下:

  当点击"跨域获取数据"的按钮时,添加一个<script>标签,用于发起跨域请求;注意看请求地址后面带了一个callback=showData的参数;showData即是回调函数名称,传到后台,用于包裹数据。数据返回到前端后,就是showData(result)的形式,因为是script脚本,所以自动调用showData函数,而result就是showData的参数。至此,我们算是跨域把数据请求回来了,但是比较麻烦,需要自己写脚本发起请求,然后写个回调函数处理数据,不是很方便。代码实现如下:

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

<body>
<input type="button" value="发送3" onclick="submitJsonp3();" />
<script src="/static/jquery-3.1.1.js"></script>
<script>
    function submitJsonp3() {
            var tag = document.createElement('script');
            tag.src = 'http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403';
            document.head.appendChild(tag);
            document.head.removeChild(tag);
        }

        function list(arg) {
            console.log(arg);
        }
</script>

</body>
</html>
View Code

       上述过程就是JSONP(JSONP - JSON with Padding是JSON的一种“使用模式”)实现跨域请求的过程,利用script标签的src属性(浏览器允许script标签跨域),设置src属性为:远程url,并通过函数包裹返回值,在本地通过与包裹返回值的函数名相同的函数获取返回值.

  在jQury中封装了JSONP,使用十分简单,使用实例如下:

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

<body>
<input type="button" value="发送3" onclick="submitJsonp3();" />
<input type="button" value="发送4" onclick="submitJsonp4();" />
<script src="/static/jquery-3.1.1.js"></script>
<script>
    function submitJsonp3() {
            var tag = document.createElement('script');
            tag.src = 'http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403';
            document.head.appendChild(tag);
            document.head.removeChild(tag);
        }

        function list(arg) {
            console.log(arg);
        }
    function submitJsonp4() {
            $.ajax({
                url: 'http://www.jxntv.cn/data/jmd-jxtv2.html',
                type: 'POST',
                dataType: 'jsonp',
                jsonp: 'callback',
                jsonpCallback: 'func'
            })
        }
        function func(arg) {
            console.log(arg);
        }
</script>

</body>
</html>
View Code

2.2 CORS实现跨域请求

>>>>>>待续

原文地址:https://www.cnblogs.com/wuxunyan/p/9232800.html