AJAX学习笔记

AJAX简介

AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
AJAX 不是新的编程语言,而是一种使用现有标准的新方法,是一种用于创建快速动态网页的技术

通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面。

XHR 创建对象

XMLHttpRequest 是 AJAX 的基础。
XMLHttpRequest 对象
所有现代浏览器均支持 XMLHttpRequest 对象(IE5 和 IE6 使用 ActiveXObject)。
XMLHttpRequest 用于在后台与服务器交换数据。

创建 XMLHttpRequest 对象的语法:

var xhr = new XMLHttpRequest();

老版本的 Internet Explorer (IE5 和 IE6)使用 ActiveX 对象:

var xhr = new ActiveXObject("Microsoft.XMLHTTP");
//ActiveXObject是ie6的一个插件总称,后面的括号是选择用哪个插件

兼容性解决:

方法一:
var xhr = null;
if (window.XMLHttpRequest)//需要在前面加上window(作用是看window下有没有XHR属性),不加的话会报错
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
  
方法二:
try {
    xhr = new XMLHttpRequest();
} catch (e) {
    xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
//try catch意思是尝试执行try{}有没有报错,有则执行catch{}传入错误信息参数e;

XHR 请求

如需将请求发送到服务器,我们使用 XMLHttpRequest 对象的 open() send() 方法:

xhr.open("GET","test1.txt",true);
//规定请求的类型、URL 以及是否异步处理请求
xhr.send();
//将请求发送到服务器。

open(method,url,async)参数:

  1. method:请求的类型(打开方式);GET 或 POST(类似于表单Form的method属性)
  2. url:文件在服务器上的位置(Form-action)
  3. async:是否异步 true(异步)或 false(同步)

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

send(string)(Form-submit):

  • string:仅用于 POST 请求

GET 还是 POST?
与 POST 相比,GET 更简单也更快,并且在大部分情况下都能用。

GET是读取,而POST是修改的意思;

GET通过url地址传输
POST通过浏览器内部传输

GET在url?后面传输数据
POST用send()传输,并要设置请求头setRequestHeader()申明发送的数据类型

用GET时,接受了后端传来的数据后会缓存到cookie里,当后端数据更新时,由于url地址没有改变,直接从cookie里读取数据,所以并不能读取到更新数据,而POST由于是用send()作为参数传输,所以不存在缓存问题
可以在url后加一个随机数或者时间戳解决:

xhr.open('get','2.get.php?username='+encodeURI('刘伟')+'&age=30&' + new Date().getTime(),true);
//时间戳前的&不能少

当用GET传输中文时,会发生乱码,要用encodeURI()进行转成url编码,而POST在申明数据类型时已经自动用encodeURI()进行转码了

然而,在以下情况中,请使用 POST 请求:

  • 无法使用缓存文件(更新服务器上的文件或数据库),也因为有缓存文件,所以GET方式相对不安全
  • 向服务器发送大量数据(POST 没有数据量限制)
  • 发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠(GET只能发送字符串类型的数据)

当使用 async=true 时,请规定在响应处于 **onreadystatechange **事件中的就绪状态时执行的函数:

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

on readystate change : 当readyState改变的时候触发
readyState : ajax工作状态

0(未初始化)还没有调用open()方法
1(载入)已调用send()方法,正在发送请求
2(载入完成)send()方法完成,已收到全部响应内容
3(解析)正在解析响应内容
4(完成)响应内容解析完成,可以在客户端调用了

status : 服务器(请求资源)状态,http状态码(如404 Not Found未找到页面,200 OK请求已成功)

responseText : ajax请求返回的内容以本文形式存放到这个属性下面,字符串类型

responseXML:返回XML形式的内容

数据获取

open()打开的接口里返回的数据是一堆数据,后端可以根据需要返回一个类数组类型或者类json类型的数据,方便前端使用;

后端可以用json_encode()方法自动根据数据转换成类数组类型或者类json类型;

数据传到前端后,前端可以用JSON方法把一个对象转成对应字符串也可以把字符串转成对应对象;

JSON(大写)是一个对象,下面有两个方法:
stringify : 可以把一个对象转成对应字符串
parse : 可以把字符串转成对应对象

var arr = [1,2,3];
var j = {left:100};
alert( JSON.stringify(arr) );
alert( JSON.stringify(j) );

var s1 = '[100,200,300]';
var a1 = JSON.parse(s1);

AJAX 跨域

跨域的问题

  • 域:域名
  • 跨域请求(访问):一个域名下的文件请求另外一个域名下的资源,就产生了跨域请求
  • AJAX有跨域请求限制

跨域问题的解决:

  1. 通过flash请求资源
  2. 通过服务端中转代理(中转),例如通过PHP中转,因为PHP也有请求资源的方法,但不涉及跨域,所以PHP先请求到资源,再用AJAX访问PHP的资源;
  3. JSONP

AJAX跨域解决之JSONP:
JSONP : json padding

通过<script>标签的src属性加载外部资源

src的作用 : 加载(包含指定的外部文件)

可以跨域包含且没有跨域问题;
被包含的资源可以是任何类型的文件(可以是txt,php等);
他只关注被包含的文件的内容是否是合法的JS;

用法:

  1. 在资源加载进来之前定义好一个函数,这个函数接收一个参数(数据),函数里面利用这个参数做一些事情
  2. 然后需要的时候通过<script>标签加载对应远程文件资源,当远程的文件资源被加载进来的时候,就会去执行我们前面定义好的函数,并且把数据当作这个函数的参数传入进去
<script>
function fn(data) {
    alert(data);//123
}
</script>
<script src="2.txt"></script>

2.txt文件内容:(类比后端文件)
fn([1,2,3]);

等于执行了fn函数并将[1,2,3]数据当作这个函数的参数传入

这样做等于是给数据命名了,因为如果加载的资源数据没有命名,就只能加载到数据,却操作不了。

又有一个问题,现在是加载到<script src="2.txt"></script>这里就会马上执行fn函数了,但我们需要按需加载fn函数,应该要动态添加<script src="2.txt"></script>而不是一开始就放在HTML里;

oBtn.onclick = function() {
    //当按钮点击的时候再去加载远程资源,让他执行
    var oScript = document.createElement('script');
    oScript.src = '2.txt';
    document.body.appendChild(oScript);
}

因为后端已经写好了默认加载2.txt文件是执行fn函数的,但是当其他函数也需要2.txt的数据呢?
这是应该让后端不要写死是默认执行fn函数,而是用参数让前端决定执行什么函数
callback作为参数传到后端;

<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>


oBtn1.onclick = function() {
    var oScript = document.createElement('script');
    oScript.src = 'getData.php?callback=fn1';
    document.body.appendChild(oScript);
}

oBtn2.onclick = function() {
    var oScript = document.createElement('script');
    oScript.src = 'getData.php?t=str&callback=fn2';
    document.body.appendChild(oScript);
}

注意:执行的函数应该要作为全局的函数;

posted @ 2017-05-05 17:56  CHENJIAJIE  阅读(155)  评论(0编辑  收藏  举报