pt32AJAX教程

AJAX

什么是AJAX

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

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

同步访问:
  当客户端向服务器发送请求时,服务器在处理的过程中,浏览器只能等待,效率较低
异步访问:
   当客户端向服务器发送请求时,服务器在处理的过程中,客户端可以做其他的操作,不需要一直等待
   
AJAX优点: 1.异步访问  2.局部刷新

使用场合:  1.搜索建议  2.表单请求、验证 3.前后端分离   

AJAX核心对象xhr

异步对象(XMLHttpRequest)简称为 xhr。称为 “异步对象”,代替浏览器向服务器发送异步的请求并接收响应[xhr 是由JS来提供的]

创建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>
django配置测试
[root@vm ~]# django-admin startproject ajax_mysite1
[root@vm ~]# cd ajax_mysite1/
[root@vm ajax_mysite1]# python3 manage.py runserver 0.0.0.0:8000

[root@vm net_note]# vim mysite5/settings.py

ALLOWED_HOSTS = ['*',]
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR,'templates')],
...        
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = "Asia/Shanghai"

[root@vm ajax_mysite1]# mkdir templates

[root@vm ajax_mysite1]# vim ajax_mysite1/urls.py

from django.contrib import admin
from django.urls import path
from . import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('test_xhr', views.test_xhr),
]


[root@vm ajax_mysite1]# vim ajax_mysite1/views.py
from django.shortcuts import render
from django.http import HttpResponse

def test_xhr(request):
    return render(request, 'test_xhr.html')
[root@vm ajax_mysite1]# vim templates/test_xhr.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>TestXhr</title>
</head>
<body>
    <button onclick="testXhr()">TestXhr</button>
    <!-- testXhr()是在script里的定义的函数 -->   
</body>
<script>
    function testXhr(){
        if(window.XMLHttpRequest){
            var xhr = new XMLHttpRequest();
            console.log(xhr);
        }else{
            var xhr = new ActiveXObject('Microsoft.XMLHTTP');
        }
    }
</script>
</html>
访问  http://192.168.1.11:8000/test_xhr
F12打开console控制台,点击TestXhr,显示如下,配置成功
XMLHttpRequest {onreadystatechange: null, readyState: 0, timeout: 0,…}

xhr 的成员

1.方法 - open()
作用:创建请求
语法:open(method,url,asyn)
参数:
    method:请求方式,取值'GET' 或 'POST'
    url:请求地址,字符串
    asyn:默认采用异步的方式  true:异步 / false:同步
    
eg:  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() 方法
  1    open()方法已经被调用
  2    send()方法已经被调用,响应头也已经被接收
  3    下载中;responseText属性已经包含部分数据
  4    下载操作已完成
4.属性 - responseText

作用:响应数据

5.属性 - status
作用:服务器端的响应状态码
    200  表示服务器正确处理所有的请求以及给出响应
    404  请求资源不存在
    500  服务器内部错误
6.事件 - onreadystatechange

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

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

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
//eg: xhr.open('get','/url?key=value&key=value',asyn)

练习:注册框的 用户名检查

[root@vm ajax_mysite1]# vim ajax_mysite1/urls.py
...
    path('test_xhr_get', views.test_xhr_get),

[root@vm ajax_mysite1]# vim ajax_mysite1/views.py
...
def test_xhr_get(request):
    return render(request, 'test_xhr_get.html')

添加存储路径,存放js文件

[root@vm ajax_mysite1]# vim ajax_mysite1/settings.py
...
# 访问路由
STATIC_URL = '/static/'
# 存储路径
STATICFILES_DIRS = (os.path.join(BASE_DIR,'static'),)
[root@vm ajax_mysite1]# mkdir -p static/js/
[root@vm ajax_mysite1]# vim static/js/common.js  #方便调用,不需要每次都写
function createXhr(){
    if(window.XMLHttpRequest){
        var xhr = new XMLHttpRequest();
        console.log(xhr);
    }else{
        var xhr = new ActiveXObject('Microsoft.XMLHTTP');
    }
    return xhr;
}
[root@vm ajax_mysite1]# vim templates/test_xhr_get.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Xhr get请求</title>
</head>
<body>
<button onclick="getXhr()">XhrGet请求</button>
</body>
<script src="/static/js/common.js"></script>

<script>
    function getXhr(){
        // 1 创建xhr对象
        var xhr= createXhr();
        // 2. 创建get请求,访问路径需要django配置
        xhr.open('GET','/test_xhr_get_server',true);
        // 3. 编写回调函数
        xhr.onreadystatechange=function(){
            if(xhr.readyState==4&&xhr.status==200){
                alert(xhr.responseText);
            }
        }
        // 4. 发送请求
        xhr.send(null);
    }
</script>
</html>

配置django

[root@vm ajax_mysite1]# vim ajax_mysite1/urls.py
...
    path('test_xhr_get_server',views.test_xhr_get_server),

[root@vm ajax_mysite1]# vim ajax_mysite1/views.py
from django.http import HttpResponse
...
def test_xhr_get_server(request):
    return HttpResponse('this is ajax data!')
访问http://192.168.1.11:8000/test_xhr_get
	点击 XhrGet请求 弹出弹窗 this is ajax data!
	
F12  Network   选Fetch/XHR   显示产生的异步请求,点击查看Preview看到弹窗的内容   
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;
    }
}
//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数据中一并提交    $需要使用jquery

注释csrf测试

[root@vm ajax_mysite1]# vim ajax_mysite1/urls.py
...
    path('test_xhr_post', views.test_xhr_post),

[root@vm ajax_mysite1]# vim ajax_mysite1/views.py
from django.http import HttpResponse
...
def test_xhr_post(request):
    if request.method == 'GET':
        return render(request, 'test_xhr_post.html')
    elif request.method == 'POST':
        # add your code here
        name = request.POST['name']
        age = request.POST['age']
        print(name, age)
        return HttpResponse("post请求提交成功")

[root@vm ajax_mysite1]# vim templates/test_xhr_post.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Xhr Post请求</title>
</head>
<body>

</body>
</html>
[root@vm ajax_mysite1]# vim ajax_mysite1/views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Xhr Post请求</title>
</head>
<body>
<p>
    用户名:<input type="text" id="name">
</p>
<p>
    年龄:<input type="text" id="age">
</p>
<p>
    <button onclick="register()">提交</button>
</p>
</body>
<script src="/static/js/common.js"></script>
<script>
    function register(){
        // 1 创建xhr对象
        var xhr = createXhr();
        // 2 创建请求
        xhr.open('POST','/test_xhr_post',true);
        // 3 设置回调函数
        xhr.onreadystatechange=function(){
            if(xhr.readyState==4&&xhr.status==200){
                alert(xhr.responseText);
            }
        }
        // 4 发送请求
        // 4.1 设置Content-Type
        xhr.setRequestHeader('Content-Type',
        'application/x-www-form-urlencoded');
        // 4.2 准备数据
        name = document.getElementById('name').value;
        age =document.getElementById('age').value;
        data = 'name='+name+'&age='+age;
        console.log(data);
        xhr.send(data);

    }
</script>
</html>
http://192.168.1.11:8000/test_xhr_post   访问提交将出现csrf问题,
#暂时注释,确保前后端通信没问题,再处理csrf
[root@vm ajax_mysite1]# vim ajax_mysite1/settings.py
#    'django.middleware.csrf.CsrfViewMiddleware',
再次访问,打印提交成功  consle能打印name & age信息  终端能打印 name age的值

处理csrf问题

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Xhr Post请求</title>
</head>
<body>
{% csrf_token %}
...
</body>
<script src="/static/js/common.js"></script>
<script src="/static/js/jquery-1.11.3.js"></script>

<script>
....
        // 4.2 准备数据
        var name = document.getElementById('name').value;
        var age =document.getElementById('age').value;
        var csrf=$("[name='csrfmiddlewaretoken']").val();
        var data = 'name='+name+'&age='+age+'&csrfmiddlewaretoken='+csrf;
        console.log(data);
        xhr.send(data);

    }
</script>
</html>
http://192.168.1.11:8000/test_xhr_post   访问直接成功
jquery对 ajax 的支持
$.ajax({})
参数对象中的属性:
	1.url : 字符串,表示异步请求的地址
	2.type : 字符串,请求方式,GETPOST
	3.data : 传递到服务器端的参数
		可以是字符串 :"name=sf.zh&age=18"
		也可以是js对象:
			{
				name:"sf.zh",
				age:18
			}
    8.contentType : 当有请求体有数据提交时,标明提交方式,默认值为'application/x-www-form-urlencoded; charset=UTF-8'

    4.dataType : 字符串,响应回来的数据的格式
		1.'html'
		2.'xml'
		3.'text' 
		4.'script'
		5.'json'
		6.'jsonp' : 有关跨域的响应格式
	5.success:回调函数,请求和响应成功时回来执行的操作
	6.error : 回调函数,请求或响应失败时回来执行的操作
	7.beforeSend : 回调函数,发送ajax请求之前执行的操作,如果return false,则终止请求

[root@vm ajax_mysite1]# vim ajax_mysite1/urls.py
...
    path('test_jq_get', views.test_jq_get),

[root@vm ajax_mysite1]# vim ajax_mysite1/views.py
...
def test_jq_get(request):
    return render(request, 'test_jq_get.html')
    
[root@vm ajax_mysite1]# vim templates/test_jq_get.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JQGet请求</title>
</head>
<script src="/static/js/jquery-1.11.3.js"></script>
<body>
<button onclick="JQGet()">JQGet</button>
</body>
</html>
http://192.168.1.11:8000/test_jq_get    #访问正常

设置异步请求

[root@vm ajax_mysite1]# vim templates/test_jq_get.html
...
</body>
<script>
    function JQGet(){
        $.ajax({
            url:'/test_jq_get_server',
            type:'get',
            success:function(res){
               //res等价与js的responseText
               alert(res);
            }
        });
    }

</script>
</html>
[root@vm ajax_mysite1]# vim ajax_mysite1/urls.py
...
    path('test_jq_get_server',views.test_jq_get_server),

[root@vm ajax_mysite1]# vim ajax_mysite1/views.py
...
def test_jq_get_server(request):
    return HttpResponse("this is JQ data!")
http://192.168.1.11:8000/test_jq_get   访问点击JQGet  返回this is JQ data!

JSON

JSON介绍

JSON:JavaScript Object Notation

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

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

1.JSON表示单个对象
1.使用 {} 表示单个对象
2.在 {} 中使用 key:value 的形式来表示属性(数据)
3.Key必须要用 " " 引起来
4.value如果是字符串的话,也需要用" "引起来
    var obj = {
            "name":"王老师",
            "age" : 30,
            "gender" : "Unknown"
    }
2.JSON表示一个数组
1.使用 [] 表示一个数组
2.数组中允许包含若干JSON对象 或 字符串
	a.使用JSON数组表示若干字符串	
    	var arr = ["王伟超","王夫人","王小超"];

	b.使用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();		$arr : jQuery中的数组
        //语法:
        $arr.each(function(index,obj){
            index:遍历出来的元素的下标
            obj:遍历出来的元素
        });
        
2.$.each()    
        //语法:
        $.each(arr,function(index,obj){});
        arr : js 中的普通数组
实验测试
[root@vm ajax_mysite1]# vim ajax_mysite1/urls.py
...
    path('test_json',views.test_json),

[root@vm ajax_mysite1]# vim ajax_mysite1/views.py
...
def test_json(request):
    return render(request, 'test_json.html')
[root@vm ajax_mysite1]# vim templates/test_json.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JSON的演示</title>
</head>
<script src="/static/js/jquery-1.11.3.js"></script>
<body>
<button onclick="testJSON()">TestJSON</button>
</body>    
</html>
[root@vm ajax_mysite1]# vim templates/test_json.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JSON的演示</title>
</head>
<script src="/static/js/jquery-1.11.3.js"></script>
<body>
    <button onclick="testJSON()">TestJSON</button>
</body>
<script>
    function testJSON(){
        // 1 json对象
        var json_obj={
            "username":"user",
            "age":20
        };
        console.log(json_obj);
        console.log(json_obj.username);
        console.log(json_obj.age);
        // 2 json数组
        var json_arr=[
            {
                "username":"user2",
                "age":20
            },
            {
                "username":"user3",
                "age":22
            }
        ]
        // 3 使用jquery的方式遍历数组两种方法
        $(json_arr).each(function(index,obj){
            console.log(index,obj.username,obj.age);
        });
        $.each(json_arr,function(index,obj){
            console.log(index,obj.username,obj.age);
        });
    }
</script>
</html>
http://192.168.1.11:8000/test_json  点击TestJSON 看consule输出

{username: 'user', age: 20}
user
20
0 'user2' 20
1 'user3' 22
0 'user2' 20
1 'user3' 22
4.后台处理JSON

前后端通信使用json串,前后端都涉计json的序列化与反序列化。

后台查询出数据再转换为JSON格式的字符串,再响应给前端
    1.后台先获取数据	类型允许为:元组|列表|字典
    2.在后台将数据转换为符合JSON格式的字符串
    3.在后台将JSON格式的字符串进行响应
5.Python中的JSON处理
import json
#序列化 - python对象变为json字符串
jsonStr = json.dumps(元组|列表|字典)  #封装,使用JsonResponse(d)
#反序列化 - 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)

#方法2
d = {'a': 1}
return JsonResponse(d)

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

#反序列化
JSON对象=JSON.parse(JSON字符串)   #jquery封装直接用

实验测试

实验准备
> create database ajax_mysite1 default charset utf8;

[root@vm ajax_mysite1]# vim ajax_mysite1/settings.py

...
DATABASES = {
    'default' : {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'ajax_mysite1',
        'USER': 'root',
        'PASSWORD': '123456',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    }
}
[root@vm ajax_mysite1]# python3 manage.py startapp user
[root@vm ajax_mysite1]# vim ajax_mysite1/settings.py
INSTALLED_APPS = [
    'user',

[root@vm ajax_mysite1]# vim user/models.py
...
class User(models.Model):
    name = models.CharField("姓名",
                            max_length=50,
                            unique=True)
    age = models.IntegerField("年龄", default=18)


[root@vm ajax_mysite1]# python3 manage.py makemigrations
[root@vm ajax_mysite1]# python3 manage.py migrate
[root@vm ajax_mysite1]# mysql -uroot -p123456 -e "use ajax_mysite1;desc  user_user;"
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| name  | varchar(50) | NO   | UNI | NULL    |                |
| age   | int(11)     | NO   |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+

[root@vm ajax_mysite1]# vim ajax_mysite1/urls.py
from django.urls import path, include
...
    path('user/',include('user.urls')),

[root@vm ajax_mysite1]# vim user/urls.py
from django.urls import path
from . import views

urlpatterns = [
    # http://127.0.0.1:8000/user/register
    path('register', views.register),
]

[root@vm ajax_mysite1]# vim user/views.py
from django.shortcuts import render

# Create your views here.
def register(request):
    if request.method == 'GET':
        return render(request, 'user/register.html')
    elif request.method == 'POST':
        # add your code here
        return HttpResponse("注册成功")

[root@vm ajax_mysite1]# mkdir -p user/templates/user
[root@vm ajax_mysite1]# vim user/templates/user/register.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户注册</title>
</head>
<body>
<script src="/static/js/jquery-1.11.3.js"></script>

<p>
    用户名:<input type="text" id="name" onblur="check_user()">
    <span id="info"></span>
</p>
<p>
    年龄:<input type="text" id="age">
</p>
<p>
    <button onclick="register()">注册</button>
</p>
</body>
</html>

初步验证

http://192.168.1.11:8000/user/register    
按钮触发异步

完善函数

[root@vm ajax_mysite1]# vim user/templates/user/register.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户注册</title>
</head>
<body>
<script src="/static/js/jquery-1.11.3.js"></script>

<p>
    用户名:<input type="text" id="name" >
</p>
<p>
    年龄:<input type="text" id="age">
</p>
<p>
    <button onclick="register()">注册</button>
</p>
<script>
    function register(){
        //alert(1111)   这里加alert,调错使用调用函数
        // 1 获取用户输入的数据
        var name = $('#name').val();
        var age = $('#age').val();
        // 2 将用户数据封装为json格式
        var params={
            "name":name,
            "age":age
        };
        console.log(params);//查看打印,OK了进行下一步
   // 3 使用ajax的方式发送异步post请求并接收响应,注释掉django的csrf策略,暂不处理
        $.ajax({
            type:'post',
            url:'/user/register',
            //前端请求后端,转json串。结合下面的views.py接收发送来看
            data:JSON.stringify(params),  
            contentType:'application/json',
            dataType:'json',
            success:function(res){
                // res是响应回来的数据{"code":200}
                if(res.code==200){
                    alert("注册成功!");
                }else{
                    alert(res.info);
                }
            }
        });
    }
</script>
</body>
</html>
[root@vm ajax_mysite1]# vim user/views.py

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

def register(request):
    if request.method == 'GET':
        return render(request, 'user/register.html')
    elif request.method == 'POST':
        # add your code here
        # 1.接收前端发送过来的数据
        json_str = request.body
        # 2. 将json串反序列化为对象
        py_obj = json.loads(json_str)
        name = py_obj['name']
        age = py_obj['age']
        print(name, age)
        # 3. 数据入库...
        try:
            User.objects.create(name=name, age=age)
        except:
            result = {"code": 10110, "info": "用户已存在"}
            return JsonResponse(result)

        # 4. 响应 {"code":200}
        # 将json格式的数据进行序列化
        result = {"code": 200}

        # result_str = json.dumps(result)
        # return HttpResponse(result_str,
        #                     content_type='application/json')
        
        # 使用JsonResponse,是HttpResponse的子类
        return JsonResponse(result)
#注释掉django的csrf策略,暂不处理
http://192.168.1.11:8000/user/register   访问注册  查看consule  打印 响应

调错,点击注册 
前端
    function register(){
        //alert(1111)     //这里加alert,调错使用调用函数
         console.log(params)   //打印函数结果
         $.ajax({     //检查固定格式
后端
    def register(request):
        print(name, age)    //数据获取
        # 3. 数据入库...     //数据创建检查
         # 4. 响应 {"       //检查响应
         
         
var params={           前端json数据创建   
JSON.stringify(params) 前端序列化,发送 
json.loads(json_str)   后端接收,反序列化,使用
JsonResponse(result)   后端序列化,返回
失去焦点触发异步

异步检测 输入的用户名

[root@vm ajax_mysite1]# vim user/templates/user/register.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户注册</title>
</head>
<body>
<script src="/static/js/jquery-1.11.3.js"></script>

<p>
    用户名:<input type="text" id="name" onblur="check_user()">
    //  οnblur="check_user()"失去焦点,执行函数
    <span id="info"></span>    // span 接收info
</p>
<p>
    年龄:<input type="text" id="age">
</p>
<p>
    <button onclick="register()">注册</button>
</p>
<script>
    function register(){
        //...
    }
    
    function check_user(){
        //alert(111);  //调试,是否调用函数
        // 1 获取用户输入的姓名
        var name = $('#name').val();
        // 2 封装为json对象
        var params={
            "name":name
        };
        console.log(params);
        // 3 发送ajax异步post请求
        // url: '/user/check'
        $.ajax({
            url:'/user/check',
            type:'post',
            data:JSON.stringify(params),
            contentType:'application/json',
            dataType:'json',
            success:function(res){
                if(res.code==200){
                    $('#info').html(res.info);
                }
            }
        });
        // 服务端响应
        // {"code":200,"info":"用户名已存在"}
        // {"code":200,"info":"用户名可用"}
    }
    
</script>
</body>
</html>
[root@vm ajax_mysite1]# vim user/urls.py
...
    path('check', views.check),

[root@vm ajax_mysite1]# vim user/views.py
...
def check(request):
    # 1. 获取前端提交的数据
    json_str = request.body
    # 2. 反序列化为py对象
    py_obj = json.loads(json_str)
    # 3. 获取用户名
    name = py_obj['name']
    print(name)
    info = ""
    try:
        user = User.objects.get(name=name)
        info = "用户名已存在"
    except:
        info = "用户名可用"
    # 4. 返回Json格式的数据
    result = {'code': 200, 'info': info}
    return JsonResponse(result)
访问测试,同名注册是否提示
点击请求触发异步
[root@vm ajax_mysite1]# vim user/urls.py
...
    path('',views.user_view),

[root@vm ajax_mysite1]# vim user/views.py
...
def user_view(request):
    return render(request, "user/user.html")
    
    
[root@vm ajax_mysite1]# vim user/templates/user/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 onclick="showusers()">显示用户信息</button>
<table border="1">
    <thead>
    <tr>
        <th>ID</th>
        <th>姓名</th>
        <th>年龄</th>
    </tr>
    </thead>
    <tbody id="show">

    </tbody>
</table>
<script>
    function showusers(){
        var html="";
        // 发送异步get请求
        $.ajax({
            type:'get',
            url:'/user/all',
            dataType:'json',
            success:function(res){
                alert(res);  //先测试函数执行,再设计函数功能
            }
        });
    }


</script>
</body>
</html>    
[root@vm ajax_mysite1]# vim user/urls.py
...
    path('all',views.all_user),


[root@vm ajax_mysite1]# vim user/views.py
...
from django.core import serializers
...
def all_user(request):
    # 1.users是QuerySet对象
    users = User.objects.all()
    # 方式一、使用Django自带的序列化器   #不常用,返回信息多余
    # # 2.将QuerySet对象序列化为json串
    # json_str = serializers.serialize('json',users)
    # # 3.返回的Json格式   
    # return HttpResponse(json_str,
    #                     content_type='application/json')
    # 方式二、自己构造json格式的数据   [{},{}]方便前端处理数据
    result = []
    for user in users:
        u_data = {}
        u_data['id'] = user.id
        u_data['name'] = user.name
        u_data['age'] = user.age
        result.append(u_data)

    # result_str = json.dumps(result)
    # return HttpResponse(result_str,
    #                     content_type='application/json')
    
    # 如果第一个参数是元组或列表,需要设置第二个safe参数的值为False
    # 如果第一个参数是字典,第二个参数safe设置为True,默认值也是True
    return JsonResponse(result, safe=False)

访问测试

http://192.168.1.11:8000/user/all     查看到json数据
http://192.168.1.11:8000/user/        点按钮 弹窗弹出,有object对象

完善函数&测试

[root@vm ajax_mysite1]# vim user/templates/user/user.html
<!DOCTYPE html>
...
            success:function(res){
                // alert(res);  //先测试函数执行,再设计函数功能
                $.each(res,function(index,obj){
                    html+="<tr>";
                    html+="<td>"+ obj.id +"</td>";
                    html+="<td>"+ obj.name +"</td>";
                    html+="<td>"+ obj.age +"</td>";
                    html+="</tr>";
                });
                // 放到tbody中
                $('#show').html(html);

            }
        });
    }

</script>
</body>
</html>    



http://192.168.1.11:8000/user/        点按钮,显示user信息

跨域

什么是跨域

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

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

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

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

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

http://www.taro.cn:80/a.html
http://www.taro.cn:8080/b.html
由于端口不同 , 所以不是"同源"
解决方案

通过

由服务器资源指定前端页面的哪个js方法来执行响应的数据

jquery 的jsonp跨域 (了解)

只能使用get操作

jsonp - json with padding
用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据

ex:
	当前地址: http://127.0.0.1:8000/index
    欲访问地址: http://localhost:8000/data?callback=xxx     # 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){}
	});
[root@vm ajax_mysite1]# vim ajax_mysite1/urls.py
...
    path('cross',views.cross),

[root@vm ajax_mysite1]# vim ajax_mysite1/views.py
...
def cross(request):
    return render(request, 'cross.html')


[root@vm ajax_mysite1]# vim templates/cross.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 onclick="test()">跨域测试</button>

<script>
    // 1 预留函数
    function print(data){
        alert(data);
    }
    // 2 跨域测试
    function test(){

        /*
        // 方式一 ,原生的js的方式
        // 1 获取body标签
        var body=document.getElementsByTagName('body')[0];
        // 2 准备script
        var script = document.createElement('script');
        script.src="http://localhost:8000/cross_server?callback=print";
        // 3 将script标签添加到body中
        body.append(script);

        // 方式二,jq的方式
        $.ajax({
            url:'http://localhost:8000/cross_server',
            type:'get',
            dataType:'jsonp',
            jsonp:'callback',
            jsonpCallback:'print'
        });
        */
        // 方式三
        $.ajax({
            url:'http://localhost:8000/cross_server',
            type:'get',
            dataType:'jsonp',
            success:function(res){
                alert(res);
            }
        });


    }


</script>
</body>
</html>    
[root@vm ajax_mysite1]# vim ajax_mysite1/urls.py
...
    path('cross_server',views.cross_server),


[root@vm ajax_mysite1]# vim ajax_mysite1/views.py
...
def cross_server(request):
    func = request.GET.get('callback')
    # 需要将返回的数据包裹在函数中
    # print("这是跨域的数据")
    return HttpResponse(func + '("这是跨域的数据")')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值