AJAX

25 篇文章 0 订阅
2 篇文章 0 订阅

1.AJAX

1.什么是AJAX

​ Asynchronous Javascript And Xml
​ 异步的 JS 和 xml(EXtensible Markup Language)

​ 通过 JS 异步的向服务器发送请 求并接收响应数据

​ 同步访问:
​ 当客户端向服务器发送请求时,服务器在处理的过程中,浏览器只能等待,效率较低

​ 异步访问:
​ 当客户端向服务器发送请求时,服务器在处理的过程中,客户端可以做其他的操作,不需要一直等待

​ AJAX优点:

​ 1.异步访问

​ 2.局部刷新

​ 使用场合:

​ 1.搜索建议

​ 2.表单验证

​ 3.前后端分离

2.AJAX核心对象 - 异步对象(XMLHttpRequest)

1.什么是XMLHttpRequest [简称为 xhr]

​ 称为 “异步对象”,代替浏览器向服务器发送异步的请求并接收响应

​ [xhr 是由JS来提供的]

2.创建 异步对象 (xhr)

​ 1.IE7+,Chrome,Firefox,Safari,Opera) -> 调用 XMLHttpRequest 生成 xhr对象

​ 2.IE低版本浏览器中(IE6以及以下) -> 调用 ActiveXObject() 生成xhr

<script>
	if(window.XMLHttpRequest){
		//支持 XMLHttpRequest
		var xhr = new XMLHttpRequest();
	}else{
		//不支持XMLHttpRequest,使用 ActiveXObject 创建异步对象
		var xhr = new ActiveXObject("Microsoft.XMLHTTP");
	}
</script>
<body>
<button onclick="testxhr()">创建xhr对象</button>
<script>
    function testxhr(){
        if(window.XMLHttpRequest){
            var xhr = new XMLHttpRequest();
            console.log(xhr);
        }else{
            var xhr = new ActiveXObject("Microsoft.XMLHTTP");            
        }
    }
</script>
</body>

3.xhr 的成员

​ 1.方法 - open()

​ 作用:创建请求

​ 语法:open(method,url,asyn)

​ 参数:

​ method:请求方式,取值’GET’ 或 ‘POST’

​ url:请求地址,字符串。(一般采用相对地址)

​ asyn:是否采用异步的方式 - true:异步 / false:同步

​ ex: xhr.open(‘GET’,’/server’,true);

​ 2.方法 - send()

​ 作用:通知xhr向服务器端发送请求

​ 语法:send(body)

​ 参数:

​ GET请求:body的值为null -> send(null)

​ POST请求:body的值为请求数据 -> send(“请求数据”)

​ 3.属性 - readyState

​ 作用:xhr状态,通过不同的xhr状态来表示xhr与服务器的交互情况

​ 由0-4共5个值来表示5个不同的状态

状态说明
0代理被创建,但尚未调用 open() 方法。
1open() 方法已经被调用。
2send() 方法已经被调用,响应头也已经被接收
3下载中; responseText 属性已经包含部分数据。
4下载操作已完成

​ 4.属性 - responseText

​ 作用:响应数据

​ 5.属性 - status

​ 作用:服务器端的响应状态码

状态吗说明
200表示服务器正确处理所有的请求以及给出响应
404请求资源不存在
500服务器内部错误

​ 6.事件 - onreadystatechange

​ 作用:每当xhr的readyState发生改变的时候都要触发的操作;

​ 也称作回调函数;当readyState的值为4且status值为200的时候,才可以获取响应数据

3.AJAX的操作步骤

1.GET请求
//1.创建xhr请求
var xhr = createXhr();
//2.创建请求 - open()
xhr.open('GET',url,asyn[true|false])
//3.设置回调函数 - onreadystatechange   #回调函数的特征:
//回调函数的特征,由用户编写,系统在满足一定条件时调用。
xhr.onreadystatechange = function(){
    if(xhr.readyState == 4 && xhr.status == 200){
        //接收响应
        xhr.responseText;
    }
}
//4.发送请求
xhr.send(null);

//注意:若含有请求参数 - URL后拼接 查询字符串 QueryString
//ex: xhr.open('get','/url?key=value&key=value',asyn)

测试练习:
vim setting.py

 INSTALLED_APPS = [
...
    'ajax_js',
]

LANGUAGE_CODE = 'zh-Hans'

TIME_ZONE = 'Asia/Shanghai'

STATICFILES_DIRS = (os.path.join(BASE_DIR,'static'),)

vim test_get.html

</head>
<script src="/static/js/common.js"></script>
<body>
<button onclick="getXhr()">getXhr</button>
<div id="show"></div>
<script>
    function getXhr(){
       xhr = createXhr();
       xhr.open("GET","/ajax_js/xhr_get_server",true);
       xhr.onreadystatechange = function(){
          if (xhr.readyState==4 && xhr.status==200){
             document.getElementById("show").innerHTML = xhr.responseText;
          }
       }
       xhr.send(null);
    }
</script>

vim views.py

from django.http import HttpResponse

def xhr_get_server(request):
    return HttpResponse('Hello Ajax from server')

vim ajax_js/usrl.py

urlpatterns = [
    path('xhr_get_server',views.xhr_get_server),
]

​vim test_get.html

<script src="/static/js/common.js"></script>
<body>
<button onclick="getXhr()">getXhr</button>
<div id="show"></div>
<script>
    function getXhr(){
       xhr = createXhr();
       xhr.open("GET","/ajax_js/xhr_get_server",true);
       xhr.onreadystatechange = function(){
          if (xhr.readyState==4 && xhr.status==200){
             document.getElementById("show").innerHTML = xhr.responseText;
          }
       }
       xhr.send(null);
    }
</script>
</body>

练习:注册框的 用户名检查
2.POST请求
//1.创建xhr请求
var xhr = createXhr();
//2.创建请求 - open()
xhr.open('post',url,asyn[true|false])
//3.设置回调函数 - onreadystatechange
xhr.onreadystatechange = function(){
    if(xhr.readyState == 4 && xhr.status == 200){
        //接收响应
        xhr.responseText;
        JSON对象= JSON.parse(xhr.responseText);
    }
}
下面两步是与get方式的区别:
//4设置Content-Type;
//默认ajax post的Content-Type为 "text/plain;charset=utf-8"
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
//5.发送请求
xhr.send('请求数据');
//请求数据同查询字符串 "uname=guoxiaonao&age=18"

注意:django中post需要传递csrf_token,否则触发响应码403,拒绝访问;

获取csrf_token方法如下

var csrf=$("[name='csrfmiddlewaretoken']").val();
#获取后,将token放在post body数据中一并提交

2.jquery对 ajax 的支持

$.ajax({})
参数对象中的属性:
	1.url : 字符串,表示异步请求的地址
	2.type : 字符串,请求方式,GETPOST
	3.data : 传递到服务器端的参数
		可以是字符串 :"name=sf.zh&age=18"
		也可以是js对象:
			{
				name:"sf.zh",
				age:18
			}
	4.dataType : 字符串,响应回来的数据的格式
		1.'html'
		2.'xml'
		3.'text' 
		4.'script'
		5.'json':jq会将json字符串转换为json对象
		6.'jsonp' : 有关跨域的响应格式
	5.success:回调函数,请求和响应成功时回来执行的操作
	6.error : 回调函数,请求或响应失败时回来执行的操作
	7.beforeSend : 回调函数,发送ajax请求之前执行的操作,如果return false,则终止请求
    8.contentType : 当有请求体有数据提交时,标明提交方式,默认值为'application/x-www-form-urlencoded; charset=UTF-8'

vim ajax_js/urls.py
path(‘test_jq_set’,views.test_jq_set),

vim views.py

def test_jq_set(request):
    return render(request,'ajax_js/test_jq_get.html')

vim test_jq_get.html


<head>
    <meta charset="UTF-8">
    <title>jq_get测试</title>
</head>
<script src="/static/js/jquery-1.11.3.js"></script>
<body>
<button id="btn">jq_get测试</button>
<div id="show"></div>
<script>
    // html文档所有元素都已加载
    $(function(){
        // 点击按钮时,事件处理函数
        $("#btn").click(function(){
            // jq 封装的ajax对象
            $.ajax({
                url:"/ajax_js/xhr_get_server",
                type:"GET",
                success:function(res){
                    $("#show").html(res);
                }
            })
        })
    })
</script>
</body>

3.JSON

1.JSON介绍

​ JSON:JavaScript Object Notation

​ 定义:是一种轻量级的数据交换格式。JS的一个语法子集;采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

​ 场景:在ajax中,允许将 复杂格式的响应数据 构建成 JSON的格式再进行响应

2.JSON表现

1.JSON表示单个对象

​ 1.使用 {} 表示单个对象

​ 2.在 {} 中使用 key:value 的形式来表示属性(数据)

​ 3.Key必须要用 " " 引起来

​ 4.value如果是字符串的话,也需要用" "引起来

    var obj = {
            "name":"王老师",
            "age" : 30,
            "gender" : "Unknown"
    }
2.JSON表示一个数组

​ 1.使用 [] 表示一个数组

​ 2.数组中允许包含若干JSON对象 或 字符串

​ 1.使用JSON数组表示若干字符串

	var arr = ["王伟超","王夫人","王小超"];

​ 2.使用JSON数组表示若干对象

    var arr = [
        {
            "name":"王老师",
            "age":30,
            "gender":"男"
                            },
        {
            "name":"王夫人",
            "age":28,
            "gender":"男"
                            }
        ];
3.使用 jq 的 each() 迭代数组

​ 回顾 JS中遍历数组

	var a = [{"name":"guoxiaonao", "age": 18 }, {"name":"guoxiaonao2", "age": 22}];
	
	for (var i = 0 ; i < a.length ; i++ ){
		var obj = a[i];
		console.log('name is ' + obj.name);
		console.log('age is '+ obj.age);
	}

​ 1.$arr.each();
$(a).each(); a 是数组
​ $arr : jQuery中的数组

        //语法:
        $arr.each(function(index,obj){
            index:遍历出来的元素的下标
            obj:遍历出来的元素
        });

​ 2.$.each()

        //语法:
        $.each(arr,function(index,obj){});
        arr : js 中的普通数组

练习test_json
加一条路由

1.vim urls.py
path(‘test_json’,views.test_json),

  1. vim views.py
    def test_json(request):
    return render(request,‘ajax_js/test_json.html’)

  2. vim test_json.html

<script src="/static/js/jquery-1.11.3.js"></script>
<body>
<button onclick="showJson()">test Json</button>
<script>
    function showJson(){
    /*
          单个对象
          var obj = {
          "uname":"tedu",
          "age":18
          };
          console.log("uname"+obj.uname);
          console.log("age"+obj.age);      */
    //    多个对象
          var json_arr = [
              {"uname":"tarena","age":20},
              {"uname":"danei","age":22}
          ]
    //jq 方法1
          $(json_arr).each(function(index,obj){
               console.log("json_arr["+ index +"]:"+obj.uname+","+obj.age);
          })
    //jq 方法2
          $.each(json_arr,function(index,obj){
               console.log("json_arr["+ index +"]:"+obj.uname+","+obj.age);
          })
    }
</script>

4.后台处理JSON

​ 在后台查询出数据再转换为JSON格式的字符串,再响应给前端

​ 1.后台先获取数据

​ 类型允许为:元组|列表|字典

​ 2.在后台将数据转换为符合JSON格式的字符串

​ 3.在后台将JSON格式的字符串进行响应

5.Python中的JSON处理
import json
#序列化 - python对象变为json字符串
jsonStr = json.dumps(元组|列表|字典)
#反序列化 - json字符串变为python对象
py_obj = json.loads(jsonStr)

​ Django中的JSON处理

#方法1 使用Django中提供的序列化类来完成QuerySet到JSON字符串的转换
from django.core import serializers
json_str = serializers.serialize('json',QuerySet)
return HttpResponse(json_str,第二个参数需要指定content-Type)

#方法2【推荐】
# 如果参数非字典结构,会报TypeError;如果需要序列化非字典结构的对象,需要添加safe=False参数。
# 注意JsonResponse会将响应头ct由html改为json
d = {'a': 1}
return JsonResponse(d)

例:加路由
path(‘test_make_json’,views.test_make_json),

vim views.py

def test_make_json(request):
    data = [{"uname":"tedu","age":18},{"uname":"tarena","age":20}]
    return JsonResponse(data,safe=False)

例2 :get请求
创建数据库
更改setting.py

  1. vim urls.py
    urlpatterns = [
    path(‘get_user’,views.get_user),
    path(‘get_user_server’,views.get_user_server),
    ]

  2. vim models.py

from django.db import models

# Create your models here.
class User(models.Model):
    username = models.CharField("用户名",max_length=20)
    age = models.IntegerField("年龄")

3.执行
python manage.py makemigrations
python manage.py migrate

  1. vim views.py
from django.http import HttpResponse,JsonResponse
from django.shortcuts import render
from django.core import serializers
from .models import User

def get_user(request):
    return render(request,'ajax_js/get_user.html')


def get_user_server(request):
    users = User.objects.all()
    user_list =[]
    for u in users:
        dic={'username': u.username,'age': u.age}
        user_list.append(dic)
    print(user_list)
    return JsonResponse(user_list, safe=False)

  1. vim ajax_js/templates/get_user.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>获取用户列表</title>
</head>
<script src="/static/js/jquery-1.11.3.js"></script>
<body>
<button id="btn">getusers</button>
<table>
    <thead>
    <tr>
        <th>用户名称</th>
        <th>年龄</th>
    </tr>
    </thead>
    <tbody id="show">

    </tbody>
</table>
<script>
    $(function(){
       $("#btn").click(function(){
           $.ajax({
           url:"/ajax_js/get_user_server",
           type:"GET",
           dataType:"json",
           success:function(res){
                var html="";
                $.each(res,function(index,obj){
                    html+="<tr>";
                    html+="<td>"+ obj.username +"</td>"
                    html+="<td>"+ obj.age + "</td>"
                    html+="</tr>"
                });
                $("#show").html(html);
           }
           })
       })
    })
</script>
</body>
</html>

例3. jQuery 的post请求

vim urls.py
path(‘test_post’,views.test_post),
path(‘test_post_server’,views.test_post_server),

vim views.py

from django.http import HttpResponse,JsonResponse
from django.shortcuts import render

def test_post(request):
    return render(request,"ajax_js/test_post.html")

def test_post_server(request):
    uname = request.POST['uname']
    age = request.POST['age']
    return  HttpResponse('-POST is ok, %s,%s'% (uname,age))

vim ajax_js/templates/ajax_js/test_post.html


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>POST请求</title>
</head>
<script src="/static/js/jquery-1.11.3.js"></script>
<script>
    $(function(){
        $("#btn").click(function(){
            $.ajax({
                url:"/ajax_js/test_post_server",
                type:"POST",
                data:{
                    "uname":$("#uname").val(),
                    "age":$("#age").val(),
                    "csrfmiddlewaretoken":$("[name='csrfmiddlewaretoken']").val()
                },
                success:function(res){
                    alert(res)
                }
            })
        })
    })
</script>
<body>
{% csrf_token %}
<p>
    用户名:<input type="text" id="uname">
</p>
<p>
    密码:<input type="text" id="age">
</p>
<p>
    <button id="btn">提交</button>
</p>
</body>
</html>

6.前端中的JSON处理
#序列化
JSON字符串=JSON.stringify(JSON对象)

#反序列化
JSON对象=JSON.parse(JSON字符串)

练习:

1,页面点击按钮 , 发送ajax 请求至后端获取用数据

2,将后端返回的用户数据显示至页面

4,跨域

1,什么是跨域

​ 跨域:非同源的网页,相互发送请求的过程,就是跨域

浏览器的同源策略:
同源:多个地址中,相同协议,相同域名,相同端口被视为是"同源"
在HTTP中,必须是同源地址才能互相发送请求,非同源拒绝请求(<script>和<img>除外)。

http://www.tedu.cn/a.html
http://www.tedu.cn/b.html
以上地址是 "同源"

http://www.tedu.cn/a.html
https://www.tedu.cn/b.html
由于 协议不同 ,所以不是"同源"

http://localhost/a.html
http://127.0.0.1/a.html
由于 域名不同 ,所以不是"同源"

http://www.tedu.cn:80/a.html
http://www.tedu.cn:8080/b.html
由于端口不同 , 所以不是"同源"
            
            #协议、域名(ip localhost和127.0.0.1) 、端口
2,解决方案

通过

3, jquery 的跨域
jsonp - json with padding   #原理  func(JSON),使用函数封建JSON
用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据

ex:
	当前地址: http://127.0.0.1:8000/index
    欲访问地址: http://localhost:8000/data?callback=xxx

	$.ajax({
		url:'xxx',
		type:'get',
		dataType:'jsonp',//指定为跨域访问
		jsonp:'callback',//定义了callback的参数名,以便获取callback传递过去的函数名
		jsonpCallback:'xxx' //定义jsonp的回调函数名
	});

	$.ajax({
		url:'xxx',
		type:'get',
		dataType:'jsonp',//指定为跨域访问
        success: function(data){}
	});

例:原始script
vim urls.py
path(‘test_cross’,views.test_cross),
path(‘cross_server’,views.cross_server),
path(‘cross_server_json’,views.cross_server_json),

vim views.py


import json
from django.http import HttpResponse,JsonResponse
from django.shortcuts import render

def cross_server(request):
    func = request.GET.get('callback')
    return HttpResponse(func+"('cross success,lalala')")
   # return render(request,'ajax_js/test_cross.html')
   
def cross_server_json(request):
    func = request.GET.get("callback")
    d = {"name":"tedu","age":18}
    jsonData = json.dumps(d)
    return HttpResponse(func+"("+ jsonData +")")

vim ajax_js/templates/ajax_js/test_cross.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>跨域get请求</title>
</head>
<script src="/static/js/jquery-1.11.3.js"></script>
<body>
<button id="btn">跨域请求</button>
<script>
 //预留函数
    function print(data){
        //alert(data);
        console.log(data);
    }
    $(function(){
        /*
        $("#btn").click(function(){
            var body = document.getElementsByTagName("body")[0];
            var script = document.createElement("script");
            script.type = "text/javascript";
            script.src = "http://localhost:80/ajax_js/cross_server?callback=print";
            body.append(script);

        })
        */

        $("#btn").click(function(){
            $.ajax({
                url:"http://localhost:80/ajax_js/cross_server_json",
                type:"get",
                dataType:"jsonp",
                jsonp:"callback",
                jsonpCallback:"print"
            })
        })
        /*
        $("#btn").click(function(){
            $.ajax({
                url:"http://localhost:80/ajax_js/cross_server_json",
                type:"GET",
                dataType:"jsonp",
                success:function(data){
                    console.log(data);
                }
            })
        })
        */

    })
</script>
</body>
</html>

访问
http://127.0.0.1/ajax_js/test_cross

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值