AJAX

Posted wssjzw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AJAX相关的知识,希望对你有一定的参考价值。

一、搭建服务器环境

 1、网站下载:www.php100.com  互联网可发者社区-》工具素材-》服务器工具-》WampServer 2.1 多语言集成包

 2、安装WampServer和普通安装一样,指定文件夹目录存放位置 但是选择目录之后,后面的一些网站的程序就会默认放到www文件夹

 3、打开WampServer集成包之后,左键点击右下角任务菜单栏的WampServer图标,会出现一个列表菜单栏

    1.www directory【directory--目录】: 点击会直接跳转到www的目录下

    2.phpMyAdmin:与数据库有关,根据需求使用

 4、访问文件下的内容:不能直接点击 在浏览器中地址栏输入 127.0.1(或者localhost)/文件名.后缀  [这里输入localhost 等同于 X:\\wamp\\www即:www文件夹存放的路径]

 5、开启WampServer时,不要打开迅雷、在线播放器等播放、下载软件,会占用Apache服务器默认的80端口 ,可能会出现问题。也会有软件冲突导致下载后无法打开--》百度一下就行

二、什么是Ajax?

 1、概念:Asynchronous javascript and XML(异步的JavaScript和XML)

  用javascript异步的形式去操作xml

 2、作用:数据交互

    -相较于直接通过浏览器获取数据[cookie] 更节省用户操作,时间,提高用户体验,减少数据请求

    -传输数据

   实例讲解:比如一个新闻页面[163.com] 有多块区域内容,但我们关心的只有一部分区域  ; 当我们去请求一个页面,服务端接受并返回给我们相应的页面内容,如果我们不主动重新请求或刷新,返回的内容是定死的,不会更改,而刷新后才请求到新的内容,这样如果服务器端更新了一条新闻,我们就不能保证在最快的时间内获取到它[因为要刷新,重新请求]--但这样整个页面都会重新请求,也就导致一些不必要的数据获取,减低了用户体验度    当我们只想刷新某一块区域,而且不用一次次点击刷新,Ajax被提了出来,它可以不通过浏览器地址栏进行请求,而是通过js中一个内置的Ajax对象完成浏览器的请求行为,告诉它你要请求的一个URL地址,然后让Ajax加载这个数据,并且可以加载片段数据,加载完成以后,在由dom操作动态的将它加载到页面中;

  3、Ajax操作流程以及兼容处理

//最简单的小例子
window.onload = function(){ var oBtn = document.getElementById(btn); oBtn.onclick = function(){ var xhr = new XMLHttpRequest(); xhr.open(get,1.txt,true); // 1.txt是www下的文件 xhr.send(); xhr.onreadystatechange = function(){ if( xhr.readystate == 4 ){ alert(xhr.responseText); } } } }

【通过F12 打开 file://开头是本地形式,会报错 通过localhost访问】

    1.打开浏览器---创建一个ajax对象

        var xhr=new XMLHttpRequest()

      IE6以下兼容:ajax不是浏览器内置的,而是通过插件外接进来的---ActiveXObject---的插件集合总称  Microsoft.XMLHTTP---微软下的XMLHTTP插件 

        var xhr=new ActiveXObject(‘Microsoft.XMLHTTP‘)

var xhr=nullif(window.XMLHttpRequest){  //不能直接用XMLHttpRequest 因为ie6下面没有XMLHttpRequest方法 所有浏览器会将其作为不存在的变量报错
    xhr = new XMLHttpRequest();
}else{
    xhr = new ActiveXObject(Microsoft.XMLHTTP);
}
/* 错误处理
try{
  xhr = new XMLHttpRequest();
  //代码尝试执行这个块中的内容,如果有错误,则会执行catch{},否则跳过catch{},并且传入一个错误信息参数e,e记录错误原因信息等
  //throw new Error(‘错了错了‘);  //手动报错 
}catch(e){
   xhr = new ActiveXObject(‘Microsoft.XMLHTTP‘);
}
*/

    2.在地址栏输入地址---open(打开方式,地址,是否异步)方法和表单

      打开方式

//get获取方式
window.onload = function(){
      var oBtn = document.getElementById(btn);

      oBtn.onclick = function(){
            var  xhr = new XMLHttpRequest();
            //xhr.open(‘get‘,‘2.get.php?username=leo&age=30‘,true); //会导致①的问题,解决方案如下
       xhr.open(get,2.get.php?username=leo&age=30&+new Date().getTime(),true); //‘2.get.php‘是传输的后端文件 ‘?username=leo&age=30‘是传输的内容 " ‘&‘+new Date() "是解决方法   
       xhr.send();


            xhr.onreadystatechange = function(){
                   if( xhr.readystate == 4 ){
                        alert(xhr.responseText);  //①下文1.get.php第二次读取的结果仍会是‘你的名字是leo,年龄是30‘
                   }
            }
      }
}

//post获取方式---数据放在send()里面作为参数传递
window.onload = function(){
      var oBtn = document.getElementById(btn);

      oBtn.onclick = function(){
            var  xhr = new XMLHttpRequest();
          
       xhr.open(post,2.post.php,true);

       xhr.setTequsetHead(content-type,application/x-www-form-urlencoded);
       xhr.send(username=leo&age=30);


            xhr.onreadystatechange = function(){
                   if( xhr.readystate == 4 ){
                        alert(xhr.responseText); 
                   }
            }
      }
}




//PHP:
//2.get.php:
<?php
header(content-type:text/html;charset="utf-8");
error_reporting(0);
//$_REQUEST //get或者post方式获取都可以
$username = $_GET[username];
$age = $_GET[age];

echo "你的名字:{$username},年龄:{$age}";  //第一次读取
//echo "欢迎,你的名字:{$username},年龄:{$age}";  //第二次读取


//2.post.php: 
<?php header(content-type:text/html;charset="utf-8");
error_reporting(0);

$username = $_POST[username];
$age = $_POST[age];

echo "你的名字:{$username},年龄:{$age}";

  get:

   提取内容--缓存:出现的问题在于浏览器的缓存:当浏览器第一次读取"2.get.php?username=leo&age=30‘内的内容之后,该地址和内容就会被缓存记录下来,第二次访问相同地址时,的时候就会从浏览器缓存中提取出内容,导致出错---解决方案:在url?后面连接一个随机数,时间戳 

   ②乱码:如果文中的leo改为中文,就可能会出现乱码,这时就需要编码

  xhr.open(get,2.get.php?username=+encodeURL(刘伟)+&age=30& + 
new Date().getTime(),true)

  post:

   ①setRequestHeader设置请求头:申明发送的数据类型、编码类型

   ②传输方式:数据是以send()的参数形式传输的

   ③提交内容--无缓存 :post无缓存

   ④无乱码--setRequestHeader:已经声明编码类型

      地址

      是否异步

        异步:非阻塞 前面的代码不会影响后面代码的执行

        同步:阻塞 前面的代码会影响后面代码的执行

<script src="jquery.js"></script>
<script>
    ${function()()}  //阻塞  如果jquery.js没有加载完,那么该句代码不会执行

    setTimeout(function(){
        alert(1);
   },2000);
   alert(2);  //非阻塞 定时器未执行时下方代码会执行输出2
</script>

      <!-- 类似的衍生-》表单:数据的提交

      action:数据提交的地址,默认是当前页面

      method:数据提交的的方式,默认是get方法

        *get--会被记录,暴露在外,会对用户的隐私造成泄露,只能传字符串类型

         把数据名称和数据值用"="连接,如果有多个的话,那么他会把多个数据组合用"&"进行连接,然后吧数据放到url?后面传到指定页面

         get请求数据大小长度本身没有限制,但由于浏览器url长度限制的原因[不同浏览器限制不同],我们不要通过get方式传递过多的数据[IE限制2000个字符 约等于 2KB]

        *post--不会被缓存,相对安全,能传多种类型的数据

          理论上无限制,后端可以设置传输最大限制post_max_size=8M[默认为8M]

技术分享图片

 

技术分享图片

         Request Headers:请求头--当我们去发送一个请求的时候带的一些额外信息

            User-Agent:当前访问你的是什么浏览器,什么型号,版本,核心,

            Referer:看这个页面的前一个地址

        Form Data: 表单数据[初始是格式化的数据] 点击view source会出现原始的传递样式,与get一样,‘=‘分隔数据和数据值,‘&‘连接多个数据

     enctype:提交的数据格式,默认application/x-www-form-urlencoded

  -->
<body>
  <form action=1.get.php method=get>  //post方式提交 action=‘1.post.php‘ method=‘post‘
    <input type=text name="username" />
   <input type=text name="age" />
   <input type=submit value="提交" />
  </form>
</body>


//1.get.php:
<?php
header(content-type:text/html;charset="utf-8");
error_reporting(0);
//$_REQUEST //get或者post方式获取都可以
$username = $_GET[username];
$age = $_GET[age];

echo "你的名字:{$username},年龄:{$age}";

//1.post.php:
<?php
header(content-type:text/html;charset="utf-8");
error_reporting(0);

$username = $_POST[username];
$age = $_POST[age];

echo "你的名字:{$username},年龄:{$age}";

    3.提交--发送请求

    4.等待服务器返回内容

     -onreadystatechange请求状态监控事件---当readystate改变的时候触发

       ·readyState属性: ajax工作状态[请求状态]

        -0(初始化)还没有调用open()方法

        -1(载入)已调用send(),正在发送请求

        -2(载入完成)send()方法完成,已收到全部响应内容[机器语言]

        -3(解析)正在解析响应内容[人类的语言]

        -4(完成)响应内容解析完成,可以在客户端调用

      ·status:服务器状态值 HTTP状态码 :不同开头表示不同状态以及错误原因

技术分享图片

      ·responseText属性:ajax请求返回的内容就被存放到这个属性下面[字符串形式]

xhr.onreadystatechange=function(){
     if(xhr.readyState==4){
        if(xhr.responseText){
             alert( xhr.responseText );
        }else{
             alert(出错了,Err: + xhr.status);
        }
     }
}

  4、Ajax获取数据的处理

   后台给我们传输数据的时候,有时想传输一个非文本(数组等...),但由于responseText,我们接受到的只有文本(如对象会以‘[1,2,3]‘字符串的形式被接收),如何将这种字符串转换为其他类型。

   JSON:对象,IE8以下不支持---解决方案:网站json.org-》javascript-》josn2.js

        stringify:可以把对象转换成对象字符串

      parse:可以把字符串转成对应对象

<script src=json2.js></script>
<script>
//stringify:可以把对象转换成对象字符串 var arr=[1,2,3]; var j = {left:100} alert( typeof JSON.stringify(arr) ); // string [1,2,3] alert( typeof JSON.stringify(j) ); //string {"left":100}  //parse:可以把字符串转成对应对象 var s1=[100,200,300]; var a2=JSON.parse(s1); alert(s2[0]); //100 var s2={"left":100}; //JSON左边的值必须加 双引号 var a2= JSON.parse(s2); alert(a2.left); //100 </script>

 三、AJAX跨域解决方案之JSONP

    跨域:跨域名

      一个域名下的文件去请求了和他不一样的域名下的资源文件,那么就会产生跨域请求问题--报错[XMLHttprequest cannot load http://api.douban.com/book/subjects?q=javascript&alt=json&max-results=1. No ‘Access-Control-Allow-Origin‘ header is present on the requested resource. Origin ‘http://localhost‘ is therefore not allowed access. ]大概意思就是 请求方在服务器没有备份,不在服务器白名单中,不予通过

      ajax跨域请求限制解决方案---网站:bob.ippoli.to

       1.通过flash请求资源[暂时不予讨论]--列入白名单 [Flash]

       2.通过服务端中转--通过服务端的代码进行代理,比如说:在当前域名下[电脑下]新建一个PHP文件,用当前PHP文件去访问外部资源,我们的文件去访问PHP资源 [Local proxy 本地代理]

      3.JSONP:json with padding---script标签:<script src=""></script>

          *为什么用script加载资源?---用script标签加载资源是没有跨域问题的

          *script能加载除.js以外的文件类型吗?---某一个文件的文件的类型不取决与它的后缀名,后缀名只是用来方便人或某些程序去辨识的,而是由实质内容决定的!所以只需要保证文件内的内容是合法的JS代码就可以。

          *内容如何应用---跨域拿过来的内容是JSON的样子[{},{},{},{}],但是我们通过script的src将内容取过来之后,都是没有用变量去存的JSON。

            1. 在资源加载进来之前定义好一个函数,这个函数接受一个参数(数据),函数里面利用这个参数做一些操作

            2. 然后需要的时候通过script标签加载对应远程文件资源,当远程的文件资源被加载进来的时候,就会去执行我们前面定义好的函数,并且把数据当做这个函数的参数传进来

技术分享图片技术分享图片

            3. 如何让内容根据我们的需求进行加载[按钮点击记载...]

<script>
function fn(data){
    alert(data);
}
</script>
<script>
   window.onload=function(){
         var oBtn=document.getElementById(btn);
        oBtn.onclick = function(){
               //当按钮点击的时候再去加载远程资源,让他执行
               var oScript = document.createElement(script);
               oScript.src = 2.txt;
               //自动在body内容最后面加载oScript
               document.body.appendChild(oScript);
        }
   }
</script>        

             4. JSONP与后台的交互实例[多数据交互]

<script>
  function fn1(data){
    var oUl1 = document.getElementById(ul1);
    var html = ‘‘;
    for(var i=0;i<data.length;i++){
      html += <li>+data[i]+</li>;
       }
    oUl1.innerHTML = html;
   }
  function fn2(data){
    var oUl2 = document.getElementById(ul2);
       var html=‘‘;
    for(var i=0;i<data.length;i++){
      html = <li>+data[i]+</li>;
       }
    oUl2.innerHTML = html;
    }
</script>
<script>
  window.onload = function(){
    var oBtn1=document.getElementById(btn1);
    var oBtn2=document.getElementById(btn2);

    oBtn1.onclick = function(){
      var oScript = document.createElement(script);
      oScript.src=getData.php&callback=fn1&t=str;  //t决定传入的数组
      document.body.appendChild(oScript);
    }
       oBtn2.onclick = function(){
          var oScript = document.createElement(script);
      oScript.src = "getData.php?callback=fn2";
      document.body.appendChild(oScript);
       }

  }
</script>
<body>
  <input type=button id="btn1" value="加载数字" />
  <input type="button" id=btn2 value="加载字母" />
</body>


//PHP
<?php
$t = isset($_GET[t])?$_GET[t]:num;
$t = isset($_GET[callback])?$_GET[callback]:fn1;

$arr1 = array(111,222,333,44,555);
$arr2 = array(aaa,bbb,ccc,ddd);

if(t = num){
  $data = json_encode($arr1);
else{
  $data = json_encode($arr2);
}
echo callback(.json_encode($arr1).);

 



以上是关于AJAX的主要内容,如果未能解决你的问题,请参考以下文章

Javascript代码片段在drupal中不起作用

前端面试题之手写promise

Ajax 片段元标记 - Googlebot 未读取页面内容

执行AJAX返回HTML片段中的JavaScript脚本

javascript AJAX片段

Spring MVC 3.2 Thymeleaf Ajax 片段