Ajax

 一. Ajax

#AJAX = 异步 JavaScript和XML(标准通用标记语言的子集)

#AJAX 是一种用于创建快速动态网页的技术。
#通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
#传统的网页(不使用 AJAX)如果需要更新内容,必须重载整个网页页面
 
#使用Javascript向服务器提出请求并处理响应而不阻塞用户!核心对象XMLHTTPRequest。通过这个对象,您的JavaScript 可在不重载页面的情况与Web服务器交换数据,即在不需要刷新页面的情况下,就可以产生局部刷新的效果

#目的:AJAX不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的Web应用程序的技术。

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

a. 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

b. 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

c. 原生Ajax 和 jQueery Ajax

1. XMLHttpRequest

2. jQuery Ajax(“jQuery Ajax本质 XMLHttpRequest 或 ActiveXObject”)

1. 原生Post/Get 和 jQuery Ajax 向后台发送请求

urlpatterns = [
    url(r'^admin/', admin.site.urls),

    url(r'^index/', views.index),
    url(r'^jQuery_add/', views.jQuery_add),
    url(r'^Ajax_add/', views.Ajax_add),

]
urls.py
from django.shortcuts import render,HttpResponse,redirect

# Create your views here.

def index(request):
    return render(request,"index.html")


def jQuery_add(request):
    a1 = int(request.POST.get("a1"))
    a2 = int(request.POST.get("a2"))
    return HttpResponse(a1+a2)


def Ajax_add(request):
    if request.method == "GET":
        a1 = int(request.GET.get("a1"))
        a2 = int(request.GET.get("a2"))
        print("Ajax_add....")
        return HttpResponse(a1+a2)
    else:
        a1 = int(request.POST.get("a1"))
        a2 = int(request.POST.get("a2"))
        return HttpResponse(a1+a2)
View.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<input type="text" id="a1"> +
<input type="text" id="a2"> =
<input type="text" id="a3">

<input type="submit" value="jQuery提交" onclick="jQuery_add()">
<input type="submit" value="Ajax_get_提交" onclick="Ajax_get_add()">
<input type="submit" value="Ajax_post_提交" onclick="Ajax_post_add()">

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

<script>
    function jQuery_add() {
        $.ajax({
            url:"/jQuery_add/",
            type:"POST",
            data:{"a1":$("#a1").val(),"a2":$("#a2").val()},
            success:function (arg) {
                $("#a3").val(arg);
            }
        })
    }

    function Ajax_get_add() {
        var xhr = new XMLHttpRequest();
        d1 = $("#a1").val();
        d2 = $("#a2").val();
        xhr.onreadystatechange = function () {
            if(xhr.readyState ==4){
                $("#a3").val(xhr.responseText)
            }
        };
        xhr.open("GET","/Ajax_add/?a1=" + d1 +"&a2=" + d2 +"");
        xhr.send();
    }
    
    function Ajax_post_add() {
        var xhr = new XMLHttpRequest();
        d1 = $("#a1").val();
        d2 = $("#a2").val();
        xhr.onreadystatechange = function () {
            if(xhr.readyState ==4){
                $("#a3").val(xhr.responseText)
            }
        };
        xhr.open("POST","/Ajax_add/");
        xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
        xhr.send("a1=" + d1 +"&a2=" + d2 +"");
    }

</script>


</body>
</html>
index.html

d. 伪Ajax (非XMLHttpRequest)

1. iframe标签

#iframe标签: 具有不刷新页面就可以发送HTTP请求的功能
#由于HTML标签的iframe标签具有局部加载内容的特性,所以可以使用其来伪造Ajax请求

iframe演示

urlpatterns = [
    url(r'^autohome/', views.autohome),
]
urls.py 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <div>
        <input type="text" id="txt1" />
        <input type="button" value="查看" onclick="changeScr();"/>
    </div>

    <iframe id="ifr" style=" 1000px;height: 2000px;" src="http://www.autohome.com.cn"></iframe>

    <script>
        function changeScr(){
            var inp = document.getElementById('txt1').value;
            document.getElementById('ifr').src = inp;
        }
    </script>
</body>
</html>
autohome.html
def autohome(request):
    return render(request,'autohome.html')
View.py

2. 通过iframe form 实现伪Ajax向后端发送请求 

urlpatterns = [

    url(r'^fake_ajax/', views.fake_ajax),

]
urls.py
def fake_ajax(request):
    if request.method == "GET":
        return render(request,"fake_ajax.html")
    else:
        print(request.POST)
        return HttpResponse("...")
View.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form id="f1" action="/fake_ajax/" method="POST" target="ifr">
        <iframe id="ifr" name="ifr" style="display: none"></iframe>
        <input type="text" name="user">
        <a onclick="submitForm()">提交</a>
    </form>
    
    <script>
        function submitForm() {
            document.getElementById("f1").submit();
            document.getElementById("ifr").onload = loadIframe;
        }

        function loadIframe() {
            var content = document.getElementById("ifr").contentWindow.document.body.innerText
            alert(content)
        }
    </script>

</body>
</html>
fake_ajax.html

二. 基于Ajax上传文件 

a. 通过创建 FormData()对象,发送字符串

urlpatterns = [
    
    url(r'^upload/', views.upload),
]
urls.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h3>原生Ajax上传文件</h3>
{#    <input type="file" id="i1">#}
<a onclick="upload()">上传</a>



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

    function upload() {
        var formdata = new FormData();  //创建一个对象
        formdata.append("k1","v1");     //字符串

        var xhr = new XMLHttpRequest();

        xhr.onreadystatechange = function () {
            if(xhr.readyState ==4){
                alert(xhr.responseText)
            }
        };
        xhr.open("POST","/upload/");
{#        xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");#}
        //发送字符串的时候不需要加上面
        xhr.send(formdata);     //发送字符串,
    }

</script>


</body>
</html>
upload.html
def upload(request):
    if request.method == "GET":
        return render(request,"upload.html")
    else:
        print(request.POST,request.FILES)
        return HttpResponse("...")
view.py

b. 原生Ajax上传文件 

urlpatterns = [
 
    url(r'^upload/', views.upload),
]
urls.py
import os
def upload(request):
    if request.method == "GET":
        return render(request,"upload.html")
    else:
        print(request.POST,request.FILES)
        file_obj = request.FILES.get("file")
        file_path = os.path.join("static",file_obj.name)
        with open(file_path,"wb") as f:
            for chunk in file_obj.chunks():
                f.write(chunk)
        return HttpResponse(file_path)
view.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h3>原生Ajax上传文件</h3>
<input type="file" id="i1">
<a onclick="upload()">上传</a>
<div id="container1">

</div>



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

    function upload() {
        var formdata = new FormData();  //创建一个对象
        formdata.append("k1","v1");
        formdata.append("file",document.getElementById("i1").files[0]);

        var xhr = new XMLHttpRequest();

        xhr.onreadystatechange = function () {
            if(xhr.readyState ==4){
                var file_path = xhr.responseText;
                var tag = document.createElement("img");
                tag.src = "/" + file_path;
                document.getElementById("container1").appendChild(tag);
            }
        };
        xhr.open("POST","/upload/");
        xhr.send(formdata);
    }

</script>


</body>
</html>
upload.html

c. jQuery 上传文件 

urlpatterns = [

    url(r'^upload/', views.upload),
]
urls.py
import os
def upload(request):
    if request.method == "GET":
        return render(request,"upload.html")
    else:
        print(request.POST,request.FILES)
        file_obj = request.FILES.get("file")
        file_path = os.path.join("static",file_obj.name)
        with open(file_path,"wb") as f:
            for chunk in file_obj.chunks():
                f.write(chunk)
        return HttpResponse(file_path)


        return HttpResponse("...")
view.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h3>原生jQery上传文件</h3>
<input type="file" id="i2">
<a onclick="upload2()">上传</a>
<div id="container2">

</div>



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



    function upload2() {
        var formdata = new FormData();  //创建一个对象
        formdata.append("k1","v1");
        formdata.append("file",$("#i2")[0].files[0]);


        $.ajax({
            url: "/upload/",
            type: "POST",
            data:formdata,
            contentType:false,
            processData:false,  //这两个参数是formdata jquery不做数据的处理 ,以原生的formdata向后端传数据
            success:function (arg) {
                var tag = document.createElement("img");
                tag.src = "/" + arg;
                $("#container2").append(tag);
            }
        })
    }


</script>


</body>
</html>
upload.html

d.伪造

urlpatterns = [
 
    url(r'^upload/', views.upload),
]
urls.py
import os
def upload(request):
    if request.method == "GET":
        return render(request,"upload.html")
    else:
        print(request.POST,request.FILES)
        file_obj = request.FILES.get("file")
        file_path = os.path.join("static",file_obj.name)
        with open(file_path,"wb") as f:
            for chunk in file_obj.chunks():
                f.write(chunk)
        return HttpResponse(file_path)


        return HttpResponse("...")
view.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h3>伪 Ajax上传文件</h3>


//enctype="multipart/form-data"  #form表单传文件加

<form id="f1" action="/upload/" method="POST" target="ifr" enctype="multipart/form-data">
    <iframe id="ifr" name="ifr" style="display: none"></iframe>
    <input type="file" name="file">
    <a onclick="upload3()">上传</a>
</form>

<div id="container3"></div>

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

    function upload3() {

        document.getElementById("f1").submit();
        document.getElementById("ifr").onload = loadIframe;
    }

    function loadIframe() {
        var content = document.getElementById("ifr").contentWindow.document.body.innerText;

        var tag = document.createElement("img");
        tag.src = "/" + content;
        $("#container3").append(tag);
    }

</script>


</body>
</html>
upload.html

三. Jsonp 

json  是一种数据格式

之前 Ajax 提交请求时候没有写IP和端口 是自己给自己发送 称作同源
现在 Ajax 提交请求时候向其它IP或端口发送请求 对方可以接收请求并返回数据 但客户端浏览器拦截不能接收跨域的数据 同源策略在限制 

同源策略是指域名 协议 端口相同 同源策略是浏览器加的

Ajax出现跨域问题  a img没有出现问题

Ajax请求 实现跨域强求数据
	- jsonp
	- cors
- 同源策略 浏览器做的限制,访问自己网站可以,访问其它网站,浏览器会限制
    - 限制    Ajax
    - 不限制  script
 
- jsonp是一种方式,目的是解决跨域问题
 
 
- 其它
    - 只能发get请求
    - 约定
 
 
- 开发需求 向其它网站发送Http请求
    - 浏览器直接发送请求[考虑同源]
    - 浏览器-->服务端-->发送请求
 
 
 
- 浏览器直接发送请求[考虑同源]
 
    - 要求:
        1. 客户端
            - URL?callback=xxx
            - function xxx(arg)
        2. 服务端
            -获取 funcname = request.GET.get(callback)
            -返回 funcname(...)
View Code

a. 自创建 script 从www.s4.com跨域向www.s5.com发送数据,接受数据 

1. www.s4.com

urlpatterns = [
    url(r'^admin/', admin.site.urls),

    url(r'^jsonp/', views.jsonp),
]
urls.py
def jsonp(request):
    return render(request,"jsonp.html")
view.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>


<input type="button" value="获取用户列表" onclick="getUsers()">

<ul id="user_list"></ul>

<script>
    function getUsers() {
        var tag = document.createElement("script");
        tag.src = "http://www.s5.com:9000/user/?callback=bbb";
        document.head.appendChild(tag);
    }

    function bbb(arg) {

        console.log(arg);
        for (var i=0 ;i<arg.length;i++){
            var tag = document.createElement("li");
            tag.innerText = arg[i];
            document.getElementById("user_list").appendChild(tag);
        }

    }
</script>


</body>
</html>
jsonp.html

2. www.s5.com

urlpatterns = [
    url(r'^admin/', admin.site.urls),

    url(r'^user', views.user),
]
urls.py
from django.shortcuts import render,HttpResponse

# Create your views here.

import json
def user(request):
    v = request.GET.get("callback")
    print("请求来了")
    user_list = ["alex","egon","root"]

    user_list_str = json.dumps(user_list)

    temp = "%s(%s)" % (v,user_list_str)
    print(temp)

    return HttpResponse(temp)
view.py

b. jQuery跨域发送数据

1. www.s4.com

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


<input type="button" value="获取用户列表" onclick="getUsers()">

<ul id="user_list"></ul>


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


    function getUsers() {
        $.ajax({
            url:"http://www.s5.com:9000/user/",
            type:"GET",
            dataType:"JSONP",
            jsonp:"callback",
            jsonpCallback:'bbb'
        //相当于 http://www.s5.com:9000/user/?callback=bbb
        })
    }

      function bbb(arg) {
          console.log(arg);
          for (var i = 0; i < arg.length; i++) {
              var tag = document.createElement("li");
              tag.innerText = arg[i];
              document.getElementById("user_list").appendChild(tag);
          }
      }

</script>

</body>
</html>
view.py

四. cors 

cors 跨站资源共享

#响应头加入
obj["Access-Control-Allow-Origin"] = "http://www.s4.com:8000"   #仅这个域名可以访问
obj["Access-Control-Allow-Origin"] = "*" 						#所有域名都可以访问

a. www.s4.com 访问 www.s5.com,在响应头加入数据,同源策略就不生效 

1. www.s4.com

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^cors/', views.cors),
]
urls.py
from django.shortcuts import render,HttpResponse

# Create your views here.


def cors(request):
    return render(request,"core.html")
view.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<input type="button" value="获取用户列表" onclick="getUsers()">

<ul id="user_list"></ul>

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

<script>
    function getUsers() {
        $.ajax({
            url:"http://www.s5.com:9000/user/",
            type:"GET",
            success:function (arg) {
                console.log(arg);
                console.log(typeof arg);
                for (var i = 0; i < arg.length; i++) {
                 var tag = document.createElement("li");
                tag.innerText = arg[i];
                document.getElementById("user_list").appendChild(tag);
                }
            }
        })
    }
</script>



</body>
</html>
core.html

www.s5.com

urlpatterns = [
    url(r'^admin/', admin.site.urls),

    url(r'^user', views.user),
]
urls.py
from django.shortcuts import render,HttpResponse

# Create your views here.

import json
def user(request):

    user_list = ["alex","egon","root"]
    user_list_str = json.dumps(user_list)

    obj = HttpResponse(user_list_str)

    obj["Access-Control-Allow-Origin"] = "http://www.s4.com:8000"
    return obj
views.py

b.预检request.method == "OPTIONS

1. www.s4.com

urlpatterns = [
    url(r'^admin/', admin.site.urls),

    url(r'^cors/', views.cors),
]
urls.py
from django.shortcuts import render,HttpResponse

# Create your views here.



def cors(request):
    return render(request,"core.html")
views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<input type="button" value="获取用户列表" onclick="getUsers()">

<ul id="user_list"></ul>

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

<script>
    function getUsers() {
        $.ajax({
            url:"http://www.s5.com:9000/user/",
            type:"DELETE",
            success:function (arg) {
                console.log(arg);
                
            }
        })
    }
</script>



</body>
</html>
core.html

2. www.s5.com

urlpatterns = [
    url(r'^admin/', admin.site.urls),

    url(r'^user', views.user),
]
urls.py
from django.shortcuts import render,HttpResponse

# Create your views here.

import json
def user(request):
    print(request.method)
    if request.method == "OPTIONS":

        obj = HttpResponse()
        obj["Access-Control-Allow-Origin"] = "*"
        obj["Access-Control-Allow-Methods"] = "DELETE"
        return obj

    obj = HttpResponse("..")
    obj["Access-Control-Allow-Origin"] = "*"
    return obj
view.py

五. 请求头

content-type

	content-type=“application/x-www-form-urlencoded”   #默认值 格式为?name=yuan&pwd=123
	content-type=“application/json”  				   #向服务器发送的是json格式  

六. Ajax 向后端发送数据

            # 方式一:

                #前端

                $.ajax({
                    url:'xx',
                    type:'post',
                    data: JSON.stringfy(pList),
                    headers:{'Content-Type':'application/json'},
                    //contentType:'json',
                    success:function(arg){
                    }
                
                })

                后端

                # 使用request.body取值
                json.loads(request.body.decode('utf-8'))
            
            # 方式二:

                #前端

                $.ajax({
                    url:'xx',
                    type:'post',
                    data: {k1: JSON.stringfy(pList),'age':18}  // k1="[....]"&age=18
                    success:function(arg){
                    }
                
                })

                #后端

                # 使用request.POST取值
                json.loads(request.POST.get('k1'))
View Code

 

  

武沛齐

原文地址:https://www.cnblogs.com/golangav/p/7126438.html