zoukankan      html  css  js  c++  java
  • AJAX(一)

    AJAX(一)

    Ajax是Asynchronous Javascript和XML的简写,这一技术能够向服务器请求额外的数据而无需卸载页面,会带来更好的用户体验。

    【前面的基础知识】
    [关于同步和异步的了解]
    同步:页面请求实时传给服务器,导致必填数据没有填的时候,要回到页面上重新从头填写,耗时长、客户体验差。
    异步:在页面必填项写上必填选项,不用通过传给服务器判断必填内容是否已经填写完整,耗时短、用户体验强。
    1、利用html+css来实现页面,表达信息;
    2、用XMLHttpRequest和web服务器进行数据的异步交换
    3、运营js操作DOM,实现动态局部刷新;
    XMLHttpRequest对象的出现分割了同步和异步。XMLHttpRequest出现之前是同步的,出现之后是异步的。

    [HTTP知识了解]
    HTTP是计算机通过网络进行通信的规则
    HTTP是一种无状态[不建立持久的连接]协议
    一个完整的HTTP请求过程,通常有7个步骤:
    1.建立TCP连接
    2.web浏览器向web服务器发送请求命令
    3.web浏览器发送请求头信息
    4.web服务器应答
    5.web服务器发送应答头信息
    6.web服务器向浏览器发送数据
    7.web服务器关闭TCP连接

    一个HTTP请求一般由4部分构成:
    1.HTTP请求的方法或动作[GET/POST]
        GET:一般用于信息获取。使用URL传递参数。对所发送信息的数量也有限制[2000字符左右]。 幂等
        POST:一般用于修改服务器上的资源。对所发送信息的数量无限制
    2.正在请求的URL
    3.请求头,包含一些客户端环境信息、身份验证信息等
    4.请求体,即请求正文,包含客户提交的查询字符串信息、表单信息等
    3和4之间一般会有一段空行 用来表示请求头的结束

    一个HTTP响应一般由3部分构成:
    1.一个数字和文字组成的状态码,用了显示请求是成功还是失败
    2.响应头,和请求头一样包含许多有用的信息如服务器类型、日期事件、内容类型和长度等
    3.响应体,即响应正文。

    HTTP状态码由3为数字构成,其中首位数字定义了状态码的类型:
    1xx:信息类,表示收到Web浏览器请求,正在进一步的处理中
    2xx:成功,表示用户请求被正确接收,理解和处理 例如 200 ok
    3xx:重定向,表示请求没有成功,客户必须采取进一步的动作
    4xx:客户端错误,表示客户端提交的请求有错误, 如 404 NOT Found,意味着请求中所引用的文档不存在
    5xx:服务器错误,表示服务器不能完成对请求的处理 如 500

    更多关于HTTP的介绍请转至:http://www.cnblogs.com/foodoir/p/5905946.html


    [XMLHttpRequest的用法]
    1、XMLHttpRequest对象创建

    var request;
    if(window.XMLHttpRequest){
          request = new XMLHttpRequest(); //IE7+,Firefox,Chrome,Opera,Safari...
    }else{
          request = new ActiveXObject("Microsoft.XMLHTTP"); //IE6,IE5
    }else{
        alert("No XHR object available.");
    }

    或者:

    function(){
        if(tyof XMLHttpRequest != "undefined"){
            return new XMLDocument();
        }else if(typeof ActiveXObject != "undefined"){
            if(typeof arguments.callee.activeXSting != "string"){
                var versions = ["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML.XMLHttp"],i,len;
            
                for(i=0,len=versions;i<len;i++){
                    try{
                        new ActiveXObj(versions[i]);
                        arguments.callee.activeXString = versions[i];
                        break;
                    }catch(ex){
                        //------
                    }
                }
            }
            return new ActiveXObject(arguments.callee.activeXString));
        }esle{
            throw new Error("No XHR object available.");
        }
    }


    2、XMLHttpRequest发送请求
    XMLHttpRequest发送请求有两个方法open和send
    open(method,url,async),有三个参数:
        method:规定HTTP发送请求的方式是get还是post,不区分大小写,一般来说用大写
        url:请求地址(相对地址或绝对地址)
        async:同步/异步(false/true),默认是异步也就是true,可以不用填写
    send(string):发送到服务器(该参数可以填或者不填-----get方法不填或填null,post:一般要填)

    get实例:

    var request = new XMLHttpRequest();
    request.open("GET","get.php",true);
    request.send();

    post实例:

    var request = new XMLHttpRequest();
    requset.open("POST","post.php",true);
    request.send();


    上面的这种做法是不正确的,POST请求的时候需要加上(一般不发送文件都用这个)request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");一定要写在open和send中间,具体做法如下:

    var request = new XMLHttpRequest();
    request.open('POST', 'post.php', true) // 默认true异步操作
    request.setRequestHeader('content-type', 'application/x-www-form-urlencoded'); //一般发送表单信息 需做该声明
    request.send('name=foodoir&sex=男');

    [XMLHttpRequest取得响应]
    在接收到响应后,响应的数据会自动填充XHR对象的属性,相关的属性简介如下:
    responseTest:作为响应主体被返回的文本
    responseXML:如果响应的内容是“text/xml”或“application/xml”,这个属性将保存包含着响应数据的XML DOM文档
    status:响应的HTTP状态
    statusText:HTTP状态的说明
    下面我们直接看一个例子:

    //先new一个xmlHttpRequest对象,再调用open方法,再发送一些数据,最后对这个响应进行监听。
    var request = new XMLHttpRequest();
    request.open("GET","get.php",true);
    request.send();
    // 为request注册监听事件
    request.onreadystatechange = function(){
      if(request.readyState === 4 && request.status === 200){
        // 当请求成功时,执行...
        ...
      }
    }

    或者说我们还可以这样做:

    var xhr = CreateXHR();
    xhr.onreadystatechange = function(){
        if(xhr.readyState == 4){//检测XHR的readyState属性
            if((xhr.status >= 200 && xhr.status <= 300) || xhr.status == 304){
                alert(xhr.responseText);
            }else{
                alert("Request was unsuccessful:" + xhr.status);
            }
        }
    };
    xhr.open("GET","get.php",true);
    xhr.send(null);

    补充:关于readyState属性值
      0:尚未初始化。open()方法还没有调用
      1:启动。open()方法已经调用,send()方法还没有调用
      2:发送。open()方法已经调用,s还没有接收到响应
      3:接收。已经接收到部分响应数据
      4:完成。已经接收全部的相应数据,而且已经可以在客户端使用了

    [PHP的一些知识]
      关于PHP的作用:PHP是一种创建动态交互性站点的服务器端脚本语言; PHP能够生成动态页面内容; PHP能够创建、打开、读取、写入、删除以及关闭服务器上的文件; PHP能够接受表单数据; PHP能够发送并取回cookies; PHP能够添加、删除、修改数据库中的数据; PHP能够限制用户访问网站中的某些页面
      为了运行PHP,我们需要搭建一个运行环境,在这里推荐以一个软件xampp(已经将我们需要的环境配置好了),其下载地址:https://www.apachefriends.org/download.html
      PHP 服务器端实现:PHP脚本以<?php 开头 以?>结尾;PHP文件的默认文件扩展名是 .php;PHP语句以分号结尾(;)
      下面我们来看一段PHP代码:

    <?php
    //echo "hello world";
    
    //这是一个纯PHP的文件,
    //设置页面内容是html编码格式是utf-8,这样防止页面返回的值是乱码
    //text/plain; application/json;text/xml;text/html;application/javascript;这都是高度客户端
    //服务器响应过来的内容它的格式是什么。text/plain;是代表格式是纯文本,application/json;是代表格式是json字符串
    
    header("Content-Type:text/plain;charst = utf-8");
    //header("Content-Type:application/json;charst = utf-8");
    //header("Content-Type:text/xml;charst = utf-8");
    //header("Content-Type:text/html;charst = utf-8");
    //header("Content-Type:application/html;charst = utf-8");
    
    //定义一个多维数组,包含员工的信息,每条员工信息为一个数组
    //它可以包含这样一个键值的方式。因为这只是一个简单的例子,所以我就把员工的信息都定义在多维数组中,不再存储数据库。
    $staff = array
    	(
    		array("name"=>"洪七","number"=>"101","sex"=>"男","job"=>"总经理"),
    		array("name"=>"郭靖","number"=>"102","sex"=>"男","job"=>"开发工程师"),
    		array("name"=>"黄蓉","number"=>"103","sex"=>"女","job"=>"产品经理"),	
    	);
    
    //判断,如果是get请求,则进行搜索;如果是post请求,则进行新建数据
    	//$_SERVER是一个超全局变量,在一个脚本的全部作用域中都可用,不用global关键字
    	//$-SERVER["REQUEST_METHOD"]返回访问页面使用的请求方法
    if($_SERVER["REQUEST_METHOD"] == "GET"){
    	search();
    }else if($_SERVER["REQUEST_METHOD"] == "POST"){
    	create();
    }
    
    //通过员工编号搜索员工
    function search(){
    //在PHP中,超全局变量,也就是我们理解的全局变量,它可以在一个脚本的全部作用域中都可以用,
    	//检查是否有员工编号的参数
    	//isset检测变量是否设置;empty判断值为否为空
    	//超全局变量 $_GET 和 $_POST 用于收集表单数据
    		//首先我们检查一下参数里边有没有员工的编号,如果没有员工的编号,我们是没法搜索员工的,所以我们用这种方式来
    		//检查一下我们的GET的url参数中有没有number这么一个字段,isset是检查变量是否设置,也就是这个number变量有没有
    		//empty代表这个变量是否为空,在这里,如果这个变量没有或者为空,我们都显示参数错误:echo "参数错误";
    		//也就是说页面直接返回“参数错误”,在浏览器中预览一下,我们没有任何参数的情况下,代表的是一个get请求,当我们没有
    		//加number参数的时候。它会直接返回参数错误,当然如果有参数错误,就直接查询了。查询,就把这个number参数获取到
    	if(!isset($_GET["number"]) || empty($_GET["number"])){
    		echo"参数错误";
    		return;
    	}
    	
    	//函数之外声明的变量拥有Global作用域,只能在函数以外进行访问
    	//global关键词用于访问函数内的全局变量
    	global $staff;
    	//获取number参数
    	$number = $_GET["number"];
    	$result = "没有找到员工。";
    	
    	//遍历$staff多维数组,查找key值为number的员工是否存在,如果存在,则返回结果
    	foreach ($staff as $value) {
    		if($value["number"] == $number){
    			$result = "找到员工:员工编号:".$value["number"].",员工姓名:".$value["name"].",员工性别:".$value["sex"].",员工职位:".$value["job"];
    			break;
    		}
    	}
    	echo $result;
    }
    
    //创建员工
    function create(){
    	//判断信息是否填写完全
    	if(!isset($_POST["name"]) || empty($_POST["name"])
    	|| !isset($_POST["number"]) || empty($_POST["number"])
    	|| !isset($_POST["sex"]) || empty($_POST["sex"])
    	|| !isset($_POST["job"]) || empty($_POST["job"])){
    		echo "参数错误,员工信息填写不全";
    		return;
    	}
    	//TODO:获取POST表单数据并保存到数据库
    	
    	//提示保存成功
    	echo "员工:".$_POST["name"]."信息保存成功!";
    }
    
    ?>
    

      PHP服务端的代码已经写完了,但是这个代码写的对不对呢,能不能顺利的执行呢,我们需要进行一下测试 这个所谓的测试可不是我们把客户端Ajax请求各个事件都给写完之后,来对它进行测试,我们需要在没有客户端的情况下,就对服务端的一些请求进行一些测试,这是怎么样来做到的呢?我们通过一个工具fiddler工具(Fiddler是一个http协议调试代理工具,它能够记录并检查所有你的电脑和互联网之间的http通讯,设置断点,查看所有的“进出”Fiddler的数据(指cookie,html,js,css等文件,这些都可以让你胡乱修改的意思)。 Fiddler 要比其他的网络调试器要更加简单,因为它不仅仅暴露http通讯还提供了一个用户友好的格式。),这个工具可以监听整个电脑所有发出的HTTP请求,可以监听它们传入的值,和相应回来的值,当然在这里边它还可以去模拟
      在百度上搜索fiddler就可以下载到,直接安装。不想下载fiddler,可以下载chrome插件postman同样的功能。
      fiddler可以监听电脑上所有的HTTP请求(GET和POST等)监听他们传入的值和返回的值。后台测试接口工具。
      使用:右边栏有compose都标签页。输入刚才地址后excuse他。双击左栏的记录。用post请求的时候要用到contentType:application/x-www-form-urlencodeed,告诉服务器是一个post请求,并且是写在url里面。
    下面我们在Fiddler软件中输入:

    GET http://localhost/php/09-21/01.php HTTP/1.1
    Host: localhost
    Proxy-Connection: keep-alive
    User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2816.0 Safari/537.36
    Accept: */*
    Referer: http://localhost/php/09-21/01.html
    Accept-Encoding: gzip, deflate, sdch, br
    Accept-Language: zh-CN,zh;q=0.8
    

    显示的结果为:参数错误,如图:
    原因分析:我们没有输入输入参数
    测试1:我们在后面传入参数,number。代码:GET http://localhost/php/09-21/01.php?number HTTP/1.1
    结果1:参数错误
    测试2:我们在后面传入参数,number=1。代码:GET http://localhost/php/09-21/01.php?number=1 HTTP/1.1
    结果2:没有没有找到员工。
    测试3:我们在后面传入参数,number=101.代码:GET http://localhost/php/09-21/01.php?number=101 HTTP/1.1
    结果3:找到员工:员工编号:101,员工姓名:洪七,员工性别:男,员工职位:总经理

    下面我们用POST方法,输入如下代码:

    POST http://localhost/php/09-21/01.php?number=101 HTTP/1.1
    Host: localhost
    Content-type: application/x-www-form-urlencoded
    Proxy-Connection: keep-alive
    User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2816.0 Safari/537.36
    Accept: */*
    Referer: http://localhost/php/09-21/01.html
    Accept-Encoding: gzip, deflate, sdch, br
    Accept-Language: zh-CN,zh;q=0.8
    Content-Length: 54
    

    结果显示为:参数错误,员工信息填写不全,如图:
    原因分析:还是没有输入参数
    测试1:我们在后面传入参数,代码:name=foodoir&number=104&sex=男&job=web前端工程师
    结果1:员工foodoir信息保存成功!效果如图:

    大家在日常进行web开发的时候,有时候后台做好之后,总是等待依赖前台做好之后,可以去调试,其实完全没有必要我们只需要约定好接口, 发送的报文和返回的报文,通过fiddler或者类似的工具,直接就可以进行调试了。不需要依赖前台是否完成,在这里推荐一个网站(http://www.imooc.com/learn/37)有专门讲解fiddler的使用方法。

    【AJAX实战】
    我们先完成html代码

    		<h1>员工查询</h1>
    		<lable>请输入员工编号:</lable>
    		<input type="text" id="keyword"/>
    		<button id="search">查询</button>
    		<p id="searchResult"></p>
    		<hr />
    		
    		<h1>员工创建</h1>
    		<lable>请输入员工姓名:</lable>
    		<input type="text" id="staffName"/><br />
    		<lable>请输入员工编号:</lable>
    		<input type="text" id="staffNumber"/><br />
    		<lable>请输入员工性别:</lable>
    		<select id="staffSex" name="sex">
    			<option>男</option>
    			<option>女</option>
    		</select><br />
    		<lable>请输入员工职位:</lable>
    		<input type="text" id="staffJob"/><br />
    		<button id="save">保存</button>
    		<p id="createResult"></p>
    		<hr />
    

    进一步完成Javascript代码

    			document.getElementById('search').onclick = function(){
    				//发送ajax请求并处理
    				var request = new XMLHttpRequest();
    				//request.open("GET","01.php")
    				request.open("GET","01.php?number="+document.getElementById("keyword").value);
    				request.send();
    				request.onreadystatechange = function(){
    					if(request.readyState === 4){
    						if(request.status === 200){
    							document.getElementById("searchResult").innerHTML = request.responseText;
    						}else{
    							alert("发生错误:"+request.status);
    						}
    					}
    				};
    			};
    			
    			document.getElementById('save').onclick = function(){
    				var request = new XMLHttpRequest();
    				request.open("POST","01.php");
    				var data = "name=" + document.getElementById("staffName").value
    							+ "&number=" + document.getElementById("staffNumber").value
    							+ "&sex=" + document.getElementById("staffSex").value
    							+ "&job=" + document.getElementById("staffJob").value;
    				request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");//在send方法中这段代码是很重要的		
    				request.send(data);
    				request.onreadystatechange = function(){
    					if(request.readyState === 4){
    						if(request.status === 200){
    							document.getElementById("createResult").innerHTML = request.responseText;
    						}else{
    							alert("发生错误"+request.status);
    						}
    					}
    				};
    			};
    

    对我们的代码进行测试,如图:

    从结果中我们可以看出,员工的查询和新建员工的保存是互不影响的,并且每一步点击都会执行相应的操作。
    然后我们发现用responseTest,纯文本的方式不太好,我们可不可以用JSON的格式来传递信息(关于更多JSON的知识,请移步至:http://www.cnblogs.com/foodoir/p/5894760.html
    这样,我们就需要对PHP中的代码进行修改,修改后的代码如下:

    <?php
    header("Content-Type:application/json;charset = utf-8");
    
    $staff = array
    	(
    		array("name"=>"洪七","number"=>"101","sex"=>"男","job"=>"总经理"),
    		array("name"=>"郭靖","number"=>"102","sex"=>"男","job"=>"开发工程师"),
    		array("name"=>"黄蓉","number"=>"103","sex"=>"女","job"=>"产品经理"),	
    	);
    if($_SERVER["REQUEST_METHOD"] == "GET"){
    	search();
    }else if($_SERVER["REQUEST_METHOD"] == "POST"){
    	create();
    }
    function search(){
    	if(!isset($_GET["number"]) || empty($_GET["number"])){
    		echo '{"success":false,"msg":"参数错误"}';
    		return;
    	}
    	global $staff;
    	$number = $_GET["number"];
    	$result = '{"success":false,"msg":"没有找到员工"}';
    	foreach ($staff as $value) {
    		if($value["number"] == $number){
    			$result = '{"success":true,"msg":"找到员工:员工编号:'.$value["number"].',员工姓名:'.$value["name"].',员工性别:'.$value["sex"].',员工职位:'.$value["job"].'"}';
    			break;
    		}
    	}
    	echo $result;
    }
    function create(){
    	if(!isset($_POST["name"]) || empty($_POST["name"])
    	|| !isset($_POST["number"]) || empty($_POST["number"])
    	|| !isset($_POST["sex"]) || empty($_POST["sex"])
    	|| !isset($_POST["job"]) || empty($_POST["job"])){
    		echo '{"success":false,"msg":"参数错误,员工信息填写不全"}';
    		return;
    	}
    	echo '{"success":true,"msg":"员工:'.$_POST["name"].'信息保存成功!"}';
    }
    ?>
    

     这里我们用到了HTTP的相关知识JSON的相关知识等,有了这些基础我们学习起AJAX还是比较简单的。后面还打算学习AJXA跨域的相关知识,jquery中使用AJXA的方法……

  • 相关阅读:
    Cookie和Session
    Servlet中关于中文乱码
    单例模式
    document对象-操作元素的文档结构
    JS实现简单的多选选项的全选反选按钮
    js实现表单验证
    servlet
    http(Hyper Text Transfer Protocol)
    Vue之webpack打包
    Flink用户画像系统之实时品牌爱好
  • 原文地址:https://www.cnblogs.com/foodoir/p/5910553.html
Copyright © 2011-2022 走看看