PHP 中学习 AJAX

400 阅读1分钟

小知识,大挑战!本文正在参与「程序员必备小知识」创作活动

本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金。

一、Ajax 原理

AJAX 即“Asynchronous JavaScript and XML”(异步的JavaScriptXML技术),指的是一套综合了多项技术的浏览器网页开发技术。

访问网站时,离不开HTTP协议,也离不开请求与响应,

用户端----请求---->服务器端

用户端<----响应----服务器端

问: 你见过哪些 Client(用户端)?

答:Firefox ,chrome,等浏览器

问: Client 只能是浏览器吗?

答: 凡是能发送 HTTP 请求的,都可称为 Client

浏览器中,提供了一个JS对象--XMLHttpRequest

它也可以帮我们发送HTTP请求,并接受Server的响应. 这意味着,我们的浏览器不提交,通过JS也可以请求服务器. Ajax,其实就是通过XHR对象,执行HTTP请求. 所以,学习的关键是---弄清XHR对象的属性和方法.

二、创建XHR对象

  1. 创建对象

var xhr = new XMLHttpRequest();

  1. 发送请求

shr.open('请求方式','URL地址',同步:false/异步:true);

  1. 传入值(使用get方式时填null,post就填需要传入的内容)

xhr.send('值');

  1. xhr对象的属性:
  • readyState:代表请求的状态
  • 0:对象已经被创建,但还没有调用open
  • 1:已经调用了onpe方法,但尚未发送请求
  • 2:请求已经发送出去了 - 3:可以接受部分相应的数据了
  • 4:已经接受了所有数据,并且关闭了连接
  • responseText:响应的内容
  • status:响应状态码,例:200,403,404等等
  • statusText:响应状态文字,例:ok,forbidden,not found等等
  1. 事件(当readyState发生变化是,会触发这个事件)

onreadystatechange=function(){};

  1. 实例:

新建一个ajax文件夹,ajax文件夹下新建ajax.html和ajax.php

<html>
    <head>
        <meta charset="UTF-8">
        <title>PHP中使用ajax</title>
    </head>
    <body>
        <input type="submit" name="ajax" value="提交" onclick="rep()">
    </body>
    <script type="text/javascript">
        var inp = document.getElementsByTagName('input')[0];
        function rep(){
            //1.创建对象
            var xhr = new XMLHttpRequest();
            //2. 发送请求
            xhr.open('get','ajax.php',true);
            //3. 传的值
            xhr.send(null);
            //4. 添加判断,设置请求完成时输出请求内容
            xhr.onreadystatechange = function (){
                if (this.readyState == 4){
                    alert(this.response)
                }
            }
        }
    </script>
</html>

php

<?php
    echo 1;
?>

点击提交后:

三、Ajax实例之验证用户名

设置通过判断用户名是否可用确认是否可注册

html页面:

<html>
    <head>
        <meta charset="UTF-8">
        <title>PHP中使用ajax</title>
    </head>
    <body>
        用户名:
        <input type="text" name="username" placeholder="请输出用户名">
        <span id="rep"></span>
        <input type="submit" name="ajax" value="提交" onclick="rep()">
    </body>
    <script type="text/javascript">
        var status = 0;
        var inp = document.getElementsByTagName('input')[0];
        inp.onblur = function (){
            //1.创建对象
            var xhr = new XMLHttpRequest();
            //2. 发送请求
            xhr.open('get','ajax.php?username='+inp.value,true);
            //3. 传的值
            xhr.send(null);
          	/* post方式
            	//2. 发送请求
              xhr.open('post','ajax.php',true);
              //3. 使用post需要设置请求头
              xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
              //4. 传的值;多参数形式:'username=' + this.value + '&page=' + this.value
              var data = 'username=' + this.value;
              xhr.send(data);
            */
            //4. 获取到span
            var span = document.getElementById('rep');
            //5. 添加判断,设置请求完成时输出请求内容
            xhr.onreadystatechange = function (){
                if (this.readyState == 4){
                    if (this.responseText == 1){
                        span.innerText = '名称已存在!';
                        span.style.color = 'red';
                        status = 0;
                    }else{
                        span.innerText = '名称可使用';
                        span.style.color = 'green';
                        status = 1;
                    }
                }
            }
        }
        function rep(){
            if (status == 1){
                alert('注册成功');
            }else{
                alert('注册失败');
            }
        }
    </script>
</html>

php页面:

<?php
		//post方式
		//$op = $_POST['username'];
    $op = $_GET['username'];
    $arr = array('lisi','zhangsan','zhaosi','liuneng');
    echo in_array($op,$arr)?1:0;
?>

效果:

四、返回值

一般ajax的返回值只有两种,分别是text和XML两种

  1. 使用json返回

html:

// 创建xhr对象
var xhr = new XMLHttpRequest();
// 使用get方式提交
xhr.open('get','json返回值.php',true);
// 需要传的参
xhr.send(null);
// 请求完成后输出结果
xhr.onreadystatechange = function (){
if (this.readyState == 4){
  // 将PHP返回数据保存起来
  var res = this.responseText;
  // 将json数据转换为js数组对象
 	var jsRes = JSON.parse(res);
  console.log(jsRes)
  console.log(typeof jsRes.name,typeof jsRes.age)
	console.log(jsRes.name,jsRes.age)
}

php:

<?php
$arr = array('name'=>'张三','age'=>18);
// 将PHP数组转换为js数组
echo json_encode($arr);
?>

结果:

  1. 使用XML(使用的较少了,这里省略)

五、同步和异步

同步和异步是什么?

    • 同时执行:代码一行行执行,上面的没执行完,下面的不许执行
    • 异步执行:上下两行代码同时执行,上面一行没执行完时,就开始执行下面的代码

例子:

html代码:

function t1(){
            // 创建xhr
            var xhr = new XMLHttpRequest();
            // true:异步请求,false:同步请求
            xhr.open('get','同步和异步.php',true);
            // 传参
            xhr.send(null);
            // 请求完成后输出
            xhr.onreadystatechange = function (){
                if (this.readyState == 4){
                    console.log(this.responseText);
                }
            }
        }
        function t2(){
            console.log(132)
        }
        t1();
        t2();

PHP代码:

<?php
sleep(3);
echo '你好';

效果:

异步时:

同步时:(虽不知为何会输出黄色的警告信息,且不会输出你好,但是效果到了就行)

大概就是你去买东西,付钱的时候发现没带钱,于是你要回家拿钱(别杠我说有手机支付)

同步:排在你后面的人等待你回家拿钱支付完毕后,她、他在付钱

异步:你回家拿钱的同时,你后面的人开始付钱

总之同步就是:你要做什么时,等多久,大家一起等(都是呆比)

异步就是:你要做什么事情时等多久,大家不一起等,大家先做

六、跨域

ajax默认不能跨域,及只能请求同域名之下的内容

通过给PHP添加请求头以达到跨域请求的目的:

Access-Control-Allow-Origin:*//域名,*代表允许所有

七、利用jsonp的方式实现跨域访问

  1. Ajax直接请求普通文件存在跨域无权限访问的问题,甭管你是静态页面、动态网页、web服

务,只要是跨域请求,一律不准;

  1. Web页面上调用js文件时则不受是否跨域的影响(不仅如此,我们还发现凡是拥有"src"这个

属性的标签都拥有跨域的能力,比如script、img、 iframe);

  1. 就是在远程服务器上设法动态的把数据装进js格式的文件里,供客户端调用和进一步处理;
  2. 客户端获取数据后,按照自己的需求进行处理,这种方式看起来像ajax,但是和ajax并没有关

系;

  1. 为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP,该协

议的一个要点就是允许用户传递一个callback参数给服务 端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。

1. 简单模拟下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>使用jsonp达到跨域请求</title>
</head>
<body>
<script type="text/javascript">
    function so(a){
        alert(a.name)
    }
</script>
<script src="http://localhost:88/PHP的学习/ajax/5.使用jsonp达到跨域请求.php"></script>
</body>
</html>

php:

// 不用加上PHP的文件头
// 伪造一个jsonp
so({'name':'张三'});

效果:

2. 利用jsonp实现获取360搜索信息

360搜索请求:

sug.so.360.cn/suggest?cal…

代码:

function so(){
        var search = document.getElementById('search')
        var url = 'http://sug.so.360.cn/suggest?callback=suggest_so&encodein=utf-8&encodeout=utf-8&format=json&fields=word,obdata&word='
            +search.value;
        var sc = document.createElement('script')
        sc.src = url;
        document.getElementsByTagName('head')[0].appendChild(sc);
    }
    // suggest_so 360的回调函数
    function suggest_so(text){
        // 接受参数是个对象,有result属性和值;循环创建
        var html ='';
        for(var i=0 ;i<text.result.length;i++){
            html = html + '<li>'+ text.result[i].word +'</li>';
        }
        document.getElementsByTagName('ul')[0].innerHTML = html;
    }

效果:

八、Ajax 配合 PHP 文件上传

自HTML5出来后,浏览器新增了FormData对象,而且XHR对象也新增了

一些功能, 可以让我们完成ajax上传,且有进度条效果。

html代码:

// style:
#box{
	width: 300px;
	height: 10px;
	border: 1px solid red;
	margin: 1px;
}
#box #prog{
	height: 10px;
	width: 0%;
	background-color: blue;
}
// html:
<form action="" method="post" enctype="multipart/form-data" target="frm">
    <input type="file" name="pic">
    <input type="submit" value="提交">
    <p>未上传文件</p>
</form>
<div id="box">
    <div id="prog"></div>
    <span>0%</span>
</div>
// js
<script type="text/javascript">
    // form表单默认一次性只能传大小最多8M的文件
    /*
    * 如果需要修改,则需要修改xampp的php.ini配置文件下的
    * post_max_size=8M
    * upload_max_filesize=8M
    * 例:post_max_size=800M
    * 修改完后需要重起xampp
    * */
    const fom = document.getElementsByTagName('form')[0];
    fom.onsubmit = function (){
        // formDate会把表单中的所有数据,整体打包给 this
        let data = new FormData(this)
        let xhr = new XMLHttpRequest()
        let p = document.getElementsByTagName('p')[0]
        xhr.onreadystatechange = function(){
          			p.innerText = '上传中'
            if (this.readyState === 4){
                p.innerText = '上传成功'
                p.style.color = 'green'
            }
        }
        // ajax 的文件上传
        xhr.upload.onprogress = function(ev){
            /* 返回值:需要实现进度条效果,只需要关注 loaded 和 total 两个参数就行
            * isTrusted: true, // ...
            * lengthComputable: true, // ...
            * loaded: 2130896, // 目前已上传的文件数量
            * total: 2130896, // 文件大小
            * type: "progress", // ...
            */
            console.log(ev)
            // 计算上传进度
            let jd = 100*ev.loaded/ev.total;
            // 因为上传的文件比较小,所以进度条会在一瞬间就满了
            // 如果想要进度效果,可将上传限制改大,在上传几十或者几百的文件
            document.getElementById('prog').style.width = jd + '%' // 上传进度条
            document.getElementsByTagName('span')[0].innerText = Math.ceil(jd) + '%' // 上传百分比
        }
        xhr.open('post','6.ajax文件上传.php',true)
        xhr.send(data)
        // 返回 false 保存上传的状态
        return false
    }
</script>

php:

<?php
	// 将上传的文件移动到当前目录
	echo move_uploaded_file($_FILES['pic']['tmp_name'],'./'.$_FILES['pic']['name']);
?>

效果:

结果: