原生ajax回调函数为什么不写就绪函数

&已上传至github&&
  如果对你有帮助的话,就去给个星吧~么么哒~笔芯
ajax:一种请求数据的方式,不需要刷新整个页面;ajax的技术核心是 XMLHttpRequest 对象;ajax 请求过程:创建 XMLHttpRequest 对象、连接服务器、发送请求、接收响应数据;
调试过程中需要搭建apache服务
HTML文件如下:(有详细的注释)
1 &!DOCTYPE html&
3 &head lang="en"&
&meta charset="UTF-8"&
&title&原生js的ajax&/title&
原生js封装ajax方法
13 &script&
//1.处理get请求
function ajax(option){
//1.实例化ajax
var xhr = window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject("microsoft.xmlhttp");
//2.判断请求方式是否为get
var isGET = /get/i.test(option.method);
//3. 将json数据转换为字符串格式
属性名=值&。。。
var data = "";
for(var i in option.data){
//4.将数据拼成字符串
data +=i+"="+ option.data[i]+"&";
//5.将处理好的数据字符串替换原有的数据
option.data =
//判断是否是get方法,如果是检查url中有没有?然后再把data数据加到?后
if(isGET){
if(option.url.indexOf("?")&0){
option.url+='?';
option.url+=+"&"+option.
//6 判断是否启用缓存,如果不启用缓存 添加时间
if(!option.cache){
//7向URL上补充时间
option.url+="&___="+new Date().getTime();
//打开连接
xhr.open(option.method,option.url,option.async);
//7.如果是post请求则设置请求头
if(!isGET){
xhr.setRequestHeader('content-type','application/xml-form-urlencoded');
//8.发送请求
xhr.send(option.data);
//9.ajax状态改变时触发函数
xhr.onreadystatechange = function(){
//判断ajax是否加载完成
if(xhr.readyState == 4){
//判断页面是否请求成功
if(xhr.status == 200){
option.success(xhr.responseText);
option.error(xhr.status)
method:'get',
url:"01.php?name=Kitty",
async:true,
data:{age:12,sex:"girl"},
cache:true,
sendBefore:function(xhr){
console.log("loading&&&");
sendComplete:function(xhr){
console.log("loading完成");
success:function(txt){
console.log("请求成功,服务器返回数据为:"+txt);
error:function(status){
console.log("请求失败状态码为:"+status);
92 &/script&
93 &/body&
94 &/html&
PHP文件如下:(仅做测试用)
echo 'get&pre&';
print_r($_GET);
echo 'post&pre&';
print_r($_POST);
运行成功后的显示:
注意:如果不是在Apache服务器下,会显示以下信息
有什么问题欢迎交流沟通~大家一起学习~
阅读(...) 评论()用户名:zzubzq
文章数:25
访问量:9716
注册日期:
阅读量:1297
阅读量:3317
阅读量:450970
阅读量:1135586
51CTO推荐博文
AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。ajax作用:在不刷新整个页面情况下,更新部分网页ajax实质:ajax全部的工作都由一个对象来做,XMLHttpRequest对像(简写xmlhttp)先给一个简单的使用xmlhttp来发送ajax请求的例子&html&&head&&script type="text/javascript"&function loadXMLDoc(){if (window.XMLHttpRequest)& {// code for IE7+, Firefox, Chrome, Opera, Safari& xmlhttp=new XMLHttpRequest();& }else& {// code for IE6, IE5& xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");& }xmlhttp.onreadystatechange=function()& {& if (xmlhttp.readyState==4 && xmlhttp.status==200)& & {& & document.getElementById("myDiv").innerHTML=xmlhttp.responseT& & }& }xmlhttp.open("GET","/ajax/test1.txt",true);xmlhttp.send();}&/script&&/head&&body&&div id="myDiv"&&h2&Let AJAX change this text&/h2&&/div&&button type="button"
AJAX 改变内容&/button&&/body&&/html&创建XMLHttpResponse对象: &xmlhttp=new XMLHttpRequest() 是后来的浏览器才支持更早的用&xmlhttp=new ActiveXObject("Microsoft.XMLHTTP")先用 if(window.XMLHttpRequest) 来判断支持,选择用哪种方式来创建该对象发送请求:xmlhttp.open() xmlhttp.send()可以通过open()的参数来配置 是 get 或者 post方式post和get区别1 post无法使用缓存&2 get发送参数的长度有限制&3 post比get更安全分析&1 只能记了&2 get的参数放在url中,url长度有限制&3 post的请求数据放在数据报中,get放在url中post方法设置请求参数示例:xmlhttp.open("post",url,true);xmlhttp.setRequestHeader("Content-type","application/x-www-from-urlencoded");xmlhttp.send("fname=Bill&name=Gates");setRequestHeader()方法 来添加 HTTP 头 至于为什么这样用? 不知道响应:xmlhttp.responseText 或者 xmlhttp.resonseXml也就是说执行完请求以后,如果执行成功,那么不用任何操作,只需要访问xmlhttp的这两个对象即可访问到响应的结果就像示例中的这样 document.getElementById("myDiv").innerHTML=xmlhttp.responseTresponseXml与resonseText区别:两者的数据格式是不同的 responseText是字符串,responseXml是xml格式xmlhttp状态标示:readyState、status、onreadystatechangereadyState存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。0: 请求未初始化1: 服务器连接已建立2: 请求已接收3: 请求处理中4: 请求已完成,且响应已就绪status:200: "OK"404: 未找到页面onreadystatechange函数,当readyState改变时被触发此时再来看示例中的这段代码是什么意思xmlhttp.onreadystatechange=function()& {& if (xmlhttp.readyState==4 && xmlhttp.status==200)& & {& & document.getElementById("myDiv").innerHTML=xmlhttp.responseT& & }& }就是说 在readyState改变时,会触发这个方法&方法体是 如果执行成功(xmlhttp.readyState==4 && xmlhttp.status==200)以 xmlhttp的readyState和status属性作为请求执行成功的依据从上述可以看出,从上传到响应,到执行状态标示,所有的动作都是xmlhttp放出的,所有的信息结果都储存在xmlhttp属性中xmlhttp是XMLHttpRequest对象的简写XMLHttpRequest 用于在后台与服务器交换数据,所有的浏览器都支持XMLHttpRequest对象以上就是ajax的本质内容不管是 jquery中的jquery.ajax()或者 jquery.post() jquery.get方法都是对这些本质内容的封装(猜测)以上所有内容可以在w3c ajax部分找到对应内容写一篇博客只为日后忘记时能快速的看一遍也加深一下记忆,讲一下自己的见解
了这篇文章
类别:未分类┆阅读(0)┆评论(0)轻松搞定Ajax(分享下自己封装ajax函数,其实Ajax使用很简单,难是难在你得到数据后来怎样去使用这些数据)_Javascript教程_动态网站制作指南
轻松搞定Ajax(分享下自己封装ajax函数,其实Ajax使用很简单,难是难在你得到数据后来怎样去使用这些数据)
来源:人气:714
轻松搞定(分享下自己封装ajax函数,其实Ajax使用很简单,难是难在你得到数据后来怎样去使用这些数据)hey,guys!今天我们一起讨论下ajax吧!此文只适合有一定ajax基础,但还是模糊状态的同志,当然高手也可以略过~~~一、概念Ajax(AsynchronousJavascrt +XML(异步Script和))二、效果实现无刷新效果,向后台异步的取数据(不是只有AJAX才能实现这样的效果的哦,如img , script标签中的src属性也可以实现一样的效果,可以自己尝试一下哦)三、本质可能我们在学习过程中会觉得ajax好难,我也是这样过来的,我觉得是我们把重心放错了。因为ajax用起来是很方便的(只是写一下请求地址,请求方式,是否异步),我们之所以觉得难,很大一部分原因是因为我们不清楚ajax内部的工作原理。我们应该把重心放在取数据后怎样去用这些数据。OK,那ajax的本质是什么呢??ajax的目的还是去后台的某个路径取数据,取文件,就像是img/srcipt标签一样,走的还是http协议!所以,如果你想了解ajax的工作原理,最好是看一下http协议,因为ajax里面所设置的参数,都是为了遵循http协议才这样写的。也不多说了,直接介绍一个我看过比较靠谱,说得很不错的视频教程,大家可以去下载学习哦(不是打广告~~真心说得好~~嘻嘻)/s/1vg4hi四、总结还是那句,ajax使用并不难,理解过后封一个ajax函数直接取数据就行, 难的是你取到数据后怎样去利用这些数据去进一步的开发。ajax运用例子: 留言本,瀑布流等等,这些取数据的方式是一样的,但对数据进行处理才是重点。ajax就像是你用script标签去引入JQ一样,这个是很简单的,但引入来之后你怎么用才是重点。OK,下面分享下我自己封装的ajajx函数(有详细注释的哦~~),用法和JQ的ajax相似,当然没JQ的那么完善,但基本够用了。 1 /* 2
*author: Ivan 3
*参数说明: 5
*opts: {'可选参数'} 6
**method: 请求方式:GET/POST,默认值:'GET'; 7
发送请求的地址, 默认值: 当前页地址; 8
**data: string, 9
**async: 是否异步:true/false,默认值:10
**cache: 是否缓存:true/false,默认值:11
**contentType: HTTP头信息,默认值:'/x-www-form-urlencoded';12
**success: 请求成功后的回调函数;13
**error: 请求失败后的回调函数;14 */15 function ajax(opts){16
//一.设置默认参数17
var defaults = {
method: 'GET',19
url: '',20
async: true,22
cache: true,23
contentType: 'application/x-www-form-urlencoded',24
success: function (){},25
error: function (){}26
//二.用户参数覆盖默认参数
for(var key in opts){30
defaults[key] = opts[key];31
//三.对数据进行处理34
if(typeof defaults.data === 'object'){
//处理 data35
var str = '';36
var value = '';37
for(var key in defaults.data){38
value = defaults.data[key];39
if( defaults.data[key].indexOf('&') !== -1 ) value = defaults.data[key].replace(/&/g, escape('&'));
//对参数中有&进行兼容处理40
if( key.indexOf('&') !== -1 )
key = key.replace(/&/g, escape('&'));
//对参数中有&进行兼容处理41
str += key + '=' + value + '&';42
defaults.data = str.substring(0, str.length - 1);44
defaults.method = defaults.method.toUpperCase();
//处理 method47 48
defaults.cache = defaults.cache ? '' : '&' + new Date().getTime() ;//处理 cache49 50
if(defaults.method === 'GET' && (defaults.data || defaults.cache))
defaults.url += '?' + defaults.data + defaults.
//处理 url
//四.开始编写ajax53
//1.创建ajax对象54
var oXhr = window.Request ? new XMLHttequest() : new ActiveXObject('Microsoft.XMLHTTP');55
//2.和服务器建立联系,告诉服务器你要取什么文件56
oXhr.open(defaults.method, defaults.url, defaults.async);57
//3.发送请求58
if(defaults.method === 'GET')
oXhr.send(null);60
oXhr.setRequestHeader("Content-type", defaults.contentType);62
oXhr.send(defaults.data);63
//4.等待服务器回应65
oXhr.onreadystatechange = function (){66
if(oXhr.readyState === 4){67
if(oXhr.status === 200)68
defaults.success.call(oXhr, oXhr.responseText);69
defaults.error();71
};74 }调用方式:如
1 ajax({ 2
3   url: '1.', 4
5   data: {name: 'ivan', sex: 'male', age: '23'}, 6
7   success: function (data){ alert('返回数据是:' + data); } 8
9 });10 11 ajax({12 13   url: '1.php',14 15   data: 'name=ivan&sex=male&age=23',16 17   cache: false,18 19   success: function (data){ alert('返回数据是:' + data); }20 21 });如有bug,请望指正; 水平有限,欢迎拍砖~~
优质网站模板& & & Ajax的基本原理是:XMLHttpRequest对象(简称XHR对象),XHR为向服务器发送请求和解析服务器响应提供了流畅的接口。能够以异步方式从服务器获得更多信息。意味着用户不必刷新页面也能取得新数据,然后通过DOM将数据插入到页面中。
XMLHttpRequest对象方法如下:
about():停止当前的请求;
open("method","URL",[asyncFlag])&:
等常见的方法;
XHR的基本用法:
在使用XHR对象时,要调用的第一个方法是open()方法,它有三个参数,第一个参数是:需要发送请求的类型(get或者post),第二个参数是请求的url,第三个参数是请求的布尔值(true是异步,false是同步);
xhr.open('get','http://127.0.0.1/ajax/ajax.php',false);
如上代码会启动一个get请求ajax.php,但是请注意:open方法并不会真正发请求,而只是启动一个请求以备发送;
要发送真正请求必须使用send()方法;如下:
xhr.open('get','http://127.0.0.1/ajax/ajax.php',false);
xhr.send(null);
send的方法接收一个参数,需要请求发送的数据,如果请求不需要发送数据,需要传送一个null,因为对于有些浏览器这是必须的;上面第三个参数传的是false,是同步请求,服务器接收到响应后再继续执行后面的代码,响应后的数据会自动填充XHR对象的属性,XHR有以下属性:
responseText: 作为响应主体被返回的文本。
responseXML: 如果响应的内容是”text/xml” 或 “application/xml”,这个属性将保存包含响应数据的XML DOM文档;
status: 响应http状态;
statusText: http状态说明;
在接收到响应后,第一步是检查status状态,如果状态时200,说明已经成功返回,此时responseText属性已经就绪;如果状态是304,说明资源未被修改,可以直接使用浏览器缓存的版本,当然,响应是有效的;如下ajax请求代码;
// 创建xhr对象方法如下:
function createXHR(){
if (window.XMLHttpRequest){
// code for IE7+, Firefox, Chrome, Opera, Safari
xhr=new XMLHttpRequest();
}else{ // code for IE6, IE5
xhr=new ActiveXObject("Microsoft.XMLHTTP");
var xhr = createXHR();
xhr.open('get','http://127.0.0.1/ajax/ajax.php',false);
xhr.send(null);
if((xhr.status &= 200 && xhr.status & 300) || xhr.status == 304) {
console.log(xhr.responseText);
console.log(xhr.status);
ajax.php代码如下:
$data = json_decode(file_get_contents("php://input"));
echo ('{"id" : ' . $data-&id . ', "age" : 24, "sex" : "boy", "name" : "huangxueming"}');
发ajax请求后,在控制台中打印如下:
说明已经请求成功;
上面的demo代码是同步请求,但是有时候我们需要发送异步请求,才能让javascript后续代码继续执行而不会堵塞,此时,我们可以检测XHR对象的readyState属性,该属性表示请求/响应当前活动阶段;这个属性取值如下:
0:未初始化。尚未调用open()方法;
1:启动。已经调用open()方法,但未调用send()方法;
2:发送。已经调用send()方法,但尚未接收到响应;
3:接收。已经接收到部分数据;
4:完成。已经接收到全部响应数据,而且可以在客户端使用了;
readyState属性值由一个值变为另一个值,就会触发一次readystatechange事件。可以利用这个事件检测每次状态变化后的readyState值,但是必须在调用open()方法之前指定onreadystatechange事件;如下代码:
// 创建xhr对象方法如下:
function createXHR(){
if (window.XMLHttpRequest){
// code for IE7+, Firefox, Chrome, Opera, Safari
xhr=new XMLHttpRequest();
// code for IE6, IE5
xhr=new ActiveXObject("Microsoft.XMLHTTP");
var xhr = createXHR();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
if((xhr.status &= 200 && xhr.status & 300) || xhr.status == 304) {
console.log(xhr.responseText);
console.log(xhr.status);
xhr.open('get','http://127.0.0.1/ajax/ajax.php',false);
xhr.send(null);
如上代码,在处理onreadystatechange事件时使用了xhr对象,没有使用this对象,原因是onreadystatechange事件处理程序的作用域的问题;如果使用this对象,在有的浏览器下会执行失败,或者导致错误发生;
理解Http头部信息
每个http请求和响应都会带有响应的头部信息,xhr对象也提供了操作这两种头部(请求头部和响应头部的)信息的方法;
默认情况下,在发送XHR请求的同时,还会发送下列头部信息:
Accept: 浏览器能够处理的内容类型;
Accept-Charset: 浏览器能够显示的字符集;
Accept-Encoding: 浏览器能够处理的压缩编码;
Accept-Language: 浏览器当前设置的语言;
Connection: 浏览器与服务器之间连接的类型;
Cookie:当前页面设置的cookie;
Host:发出请求页面所在的域;
Referer:发出请求的页面url。
User-Agent: 浏览器的用户代理字符串。
如下ajax.php请求所示:
我们还可以使用setRequestHeader()方法可以设置自定义的请求头部信息,这个方法接收2个参数:头部字段的名称和头部字段的值;要成功发送请求头部信息,必须在调用open()方法之后且调用send()方法之前调用setRequestHeader();如下demo所示:
xhr.open('get','http://127.0.0.1/ajax/ajax.php',false);
xhr.setRequestHeader("myHeader","myValue");
xhr.send(null);
截图如下:
调用getAllResponseHeaders()方法则可以取得一个包含所有头部信息的长字符串,如上代码中在onreadystatechange事件中添加getAllResponseHeaders()方法:
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
if((xhr.status &= 200 && xhr.status & 300) || xhr.status == 304) {
var myHeader = xhr.getAllResponseHeaders();;
console.log(myHeader);
console.log(xhr.status);
打印如下:
理解GET请求
在ajax中,有常见的get请求或者post请求,使用get请求时,我们是把参数的名-值对经过encodeURIComponent()进行编码,然后放到URL的末尾,所有名值对必须由和好(&)分割;如下代码:
xhr.open('get','http://127.0.0.1/ajax/ajax.php?name1=value1&name2=value2',true);
下面我们可以封装一个方法可以辅助向现有的URL的末尾添加查询字符串参数;
function addURLParam(url,name,value) {
url += url.indexOf("?") == -1 ? "?" : "&";
url += encodeURIComponent(name) + "=" + encodeURIComponent(value);
如下代码测试:
// 创建xhr对象方法如下:
function createXHR(){
if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari
xhr=new XMLHttpRequest();
}else{ // code for IE6, IE5
xhr=new ActiveXObject("Microsoft.XMLHTTP");
var xhr = createXHR();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
if((xhr.status &= 200 && xhr.status & 300) || xhr.status == 304) {
var myHeader = xhr.getAllResponseHeaders();;
console.log(myHeader);
console.log(xhr.responseText);
console.log(xhr.status);
var url = "http://127.0.0.1/ajax/ajax.php";
url = addURLParam(url,"name1","value1");
url = addURLParam(url,"name2","value2");
xhr.open('get',url,true);
xhr.setRequestHeader("myHeader","myValue");
xhr.send(null);
function addURLParam(url,name,value) {
url += url.indexOf("?") == -1 ? "?" : "&";
url += encodeURIComponent(name) + "=" + encodeURIComponent(value);
如下截图所示:
理解POST请求:
Post请求时作为请求的主体提交,post请求的主体可以是非常多的数据,而且格式不限;在open方法的第一个参数传入post,就可以初始化post请求,如下:xhr.open('post',"http://127.0.0.1/ajax/ajax.php",true);
接下来我们需要使用send()方法来发送数据,传入的参数可以是任何的字符串或者form表单序列化之后的数据;比如我们现在可以使用xhr来模仿表单提交数据,首先我们需要将Content-Type头部信息设置为application/x-www-form-urlencoded, 也就是表单提交的内容类型,其次以适当的格式创建一个字符串,比如form表单序列化数据,然后通过xhr发送到服务器端,
如下HTML代码:
&form id="form"&
&input name="user-name" value="aaa"/&
&input name="user-email" value="233"/&
JS代码如下:
// 序列化的代码
function serialize(form) {
var arrs = [],
field = null,
for(i = 0,len = form.elements. i & i++) {
field = form.elements[i];
switch(field.type) {
case "select-one":
case "select-multiple":
if(field.name.length) {
for(j = 0,optLen = field.options. j & optL j++) {
option = field.options[j];
if(option.selected) {
optValue = '';
if(option.hasAttribute) {
optValue = option.hasAttribute("value") ? option.value : option.
optValue = option.attributes["value"].specified ? option.value : option.
arrs.push(encodeURIComponent(field.name) + "=" +encodeURIComponent(optValue));
case undefined: //字段集
case "file": // 文件输入
case "submit": // 提交按钮
case "reset": // 重置按钮
case "button": // 自定义按钮
case "radio": // 单选框
case "checkbox": // 复选框
if(!field.checked) {
/* 执行默认动作 */
// 不包含没有名字的表单字段
if(field.name.length) {
arrs.push(encodeURIComponent(field.name) + "=" +encodeURIComponent(field.value));
return arrs.join("&");
var url = "http://127.0.0.1/ajax/ajax.php";
xhr.open('post',"http://127.0.0.1/ajax/ajax.php",true);
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
var form = document.getElementById("form");
xhr.send(serialize(form));
之后我们可以看到form表单序列化之后传过去的数据如下:
XMLHttpRequest 2级
XMLHttpRequest 1级只是把已有的xhr对象的实现细节描述出来了,而XMLHttpRequest 2级是在原来的基础上增加了一些规范,但所有的浏览器只是实现了他规定的部分内容;如下几个:
理解FormData
现在web应用中频繁使用的一项功能是form表单序列化,XMLHttpRequest 2级定义了FormData类型,使用FormData获取数据与表单序列化数据一样,但是更简洁方便;
支持FormData浏览器有:firefox4+, safari5+, chrome和Android3+版的webkit.
比如我现在提交form表单数据如下demo:
HTML代码:
&form id="form"&
&input name="user-name" value="aaa"/&
&input name="user-email" value="233"/&
JS代码如下:
var url = "http://127.0.0.1/ajax/ajax.php";
xhr.open('post',"http://127.0.0.1/ajax/ajax.php",true);
var form = document.getElementById("form");
xhr.send(new FormData(form));
在chrome浏览器下如下:
在firefox浏览器如下:
使用formData的方便之处体现在不必明确地在XHR对象上设置请求头部,XHR对象能识别传入的数据类型是FormData实例,并配置适当的头部信息。
理解超时设定
IE8为XHR对象添加了一个timeout属性,表示请求在等待响应多少毫秒之后停止,在给timeout设置一个数值后,如果在规定的时间之内浏览器没有接受到响应,那么就会触发ontimeout事件,那么就会终止ajax请求,如下代码:
var url = "http://127.0.0.1/ajax/ajax.php";
xhr.open('get',"http://127.0.0.1/ajax/ajax.php",true);
xhr.timeout = 1;
xhr.ontimeout = function(){
alert("111");
xhr.send(null);
如上我把代码timeout设置1毫秒,如果请求1毫秒之后没有返回数据的话,就执行ontimeout事件,并且请求停止掉,目前我测试的浏览器chrome和firefox都支持;如下chrome浏览器截图如下:
Progress Events规范是W3C的一个工作草案,定义了与客服端服务器通信有关的事件,这些事件最早是针对XHR操作的,有以下6个事件;
loadstart: 在接收到响应数据的第一个字节时触发;
progress: 在接收响应期间持续不断的触发;
error: 在请求发生错误时触发;
abort: 在因为调用abort()方法而终止连接时触发;
load:在接收到完整的响应数据时触发;
loadend:在通信完成或者触发error,abort或load事件后触发;(这个事件基本上不使用的。)
支持前5个事件的浏览器有:firefox3.5+,safari4+,chrome,IOS版的safari和android版的webkit,opera(从11开始),IE8+只支持load事件;
Firefox在实现XHR对象的某个版本时,为了简化异步交互模型,实现了load事件,用以替代readystatechange事件,响应接收完毕后触发load事件,因此就没有必要检查readyState属性了;
目前支持的浏览器有:firefox,opera,chrome和safari
如下代码演示:
var xhr = createXHR();
xhr.onload = function(){
if((xhr.status &= 200 && xhr.status & 300) || xhr.status == 304) {
console.log(xhr.responseText);
console.log(xhr.status);
xhr.open('get',"http://127.0.0.1/ajax/ajax.php",true);
xhr.send(null);
progress事件
这个事件在浏览器接收数据期间周期性的触发,而onprogress事件处理程序会接收一个event对象,包含三个属性,lengthComputable是一个表示进度信息是否可用的布尔值;position表示已经接收的字节数,totalSize表示根据Content-Length响应头部确定的预期总字节数。如下代码:
var xhr = createXHR();
xhr.onload = function(){
if((xhr.status &= 200 && xhr.status & 300) || xhr.status == 304) {
console.log(xhr.responseText);
console.log(xhr.status);
xhr.onprogress = function(event) {
var divStatus = document.getElementById("status");
if (event.lengthComputable){
divStatus.innerHTML = "Received " + event.position + " of " +
event.totalSize +" bytes";
xhr.open('get',"http://127.0.0.1/ajax/ajax.php",true);
xhr.send(null);
截图运行如下:
跨源资源共享
通过XHR实现ajax通信的一个主要限制,来源于跨域安全策略。默认情况下,XHR对象只能访问与包含它的页面位于同一个域中的资源,因为浏览器这样做的限制就是防止一些恶意操作;那么CORS(跨源资源共享)的基本原理是:需要由服务器发送一个响应标头就可以让浏览器与服务器进行沟通;
比如我现在做一个demo来试着看,假如我现在在hosts文件下绑定2个IP地址:如下:
127.0.0.1&
127.0.0.1&
那么现在我 下有一个页面ajax.html,如下代码:
var xhr = createXHR();
xhr.onload = function(){
if((xhr.status &= 200 && xhr.status & 300) || xhr.status == 304) {
console.log(xhr.responseText);
console.log(xhr.status);
xhr.open('POST',"/ajax/ajax.php",true);
xhr.send(null);
如上代码,在给域下 下的ajax.php发ajax请求,因为是同源策略问题,肯定不成功,如下所示:
现在我们在域下php设置头部即可;如下代码:
header("Access-Control-Allow-Origin: *");
ajax.php代码如下:
header("Access-Control-Allow-Origin: *");
$data = json_decode(file_get_contents("php://input"));
echo ('{"id" : ' . $data-&id . ', "age" : 24, "sex" : "boy", "name" : "huangxueming"}');
这样就可以认为大功告成,很高兴,看到书上或者网上查找资料后,也是这么说的,但是呢 当我再次请求这个页面的时候 还是发现因为同源策略的问题,请求不成功,查看控制台这样的错误,如下:
XMLHttpRequest cannot load http:///ajax/ajax.php. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '' is therefore not allowed access.
也是同源策略的问题,不允许访问;继续通过网上查找资料,发现原来是我的php.ini里面的配置出了问题,在php安装目录下找到php.ini文件output_buffering默认为off的。我现在把它设为on就OK了。如下截图所示:
我们继续重启下php服务器,即可看到请求成功,这时候我们会喜出往外;这时候我们再看看php请求如下设置:
在php文件头部设置header,header("Access-Control-Allow-Origin: *");星号意思是所有的请求都可以,但是设置并不安全,所以我们可以针对当前的这个页面域下设置,如下:
header("Access-Control-Allow-Origin: ");
$data = json_decode(file_get_contents("php://input"));
echo ('{"id" : ' . $data-&id . ', "age" : 24, "sex" : "boy", "name" : "huangxueming"}');
我们继续截图如下看看:
同样也可以访问;但是上面的在IE7-8下还是会报错,因为同源策略的问题,会报错,如下截图所示:
标准浏览器下比如chrome或者firefox不会报错,那么我们可以看下在IE下,IE如何实现对CORS的支持;
IE CORS的实现方式如下:
微软在IE中引入XDR(XDomainRequest)类型,这个对象与XHR类似,但是能实现安全可靠的跨域通信,XDR对象部分实现了W3C的CORS规范;XDR与XHR不同之处如下:
Cookie不会随请求发送,也不会随响应返回。
只能设置请求头部信息中的Content-Type字段。
不能访问响应头部信息。
只支持get和post请求。
这些变化使CSRF(Cross-Site Request Forgery,跨站点请求伪造)和XSS(Cross-Site Scripting,跨站点脚本)的问题得到了缓解,被请求的资源可以根据它认为合适的任意数据(用户代理,来源页面等)来决定是否设置Accept-Control-Allow-Origin头部。作为请求的一部分,Origin头部的值表示请求的来源域,以便远程资源明确地识别XDR请求。
XDR对象的使用方法与XHR对象非常相似,先创建一个XDomainRequest对象,如下:
var xdr = new XDomainRequest();
再调用open()方法,再调用send()方法;但是XDR对象的open()方法只接受2个参数,请求的类型和URL;
所有XDR的请求都是异步的,不能用来创建同步请求,请求成功后,会触发load事件,响应的数据保存在responseText属性中;如下demo,我们继续看下在IE7-8下如何可以跨域请求成功;如下代码:
var xdr = new XDomainRequest();
xdr.onload = function() {
alert(xdr.responseText);
xdr.open('POST',"/ajax/ajax.php",true);
xdr.send(null);
现在我们刷新下页面可以看到请求成功了,如下所示:
如果响应失败的话,会调用error方法,通知开发人员,如下代码:
var xdr = new XDomainRequest();
xdr.onload = function() {
alert(xdr.responseText);
xdr.onerror = function(){
alert("响应失败");
xdr.open('POST',"/ajax/ajax.php",true);
xdr.send(null);
与XHR一样,XDR对象也支持timeout属性以及ontimeout事件处理程序,如下代码:
xdr.timeout = 1;
xdr.ontimeout = function(){
alert("Request took too long.");
请求超过1毫秒后没有响应,就调用ontimeout事件;
标准浏览器下实现对CORS的实现
其实实现方式在第一次讲解跨域的时候我们已经讲过了,可以翻到上面,但是我们现在重新来理一遍;
Firefox3.5+,Safari4+,chrome,ios版的safari和android平台中的webkit都通过XMLHttpRequest对象实现了CORS的原生支持;如下代码:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (xhr.readyState == 4){
if((xhr.status &= 200 && xhr.status & 300) || xhr.status == 304) {
alert(xhr.responseText);
console.log(xhr.status);
xhr.open('POST',"/ajax/ajax.php",true);
xhr.send(null);
如上代码即可就可以实现在标准浏览器下ajax的跨域通信问题;
与IE中的XDR对象不同,通过跨域XHR对象可以访问status和statusText属性,而且还支持同步请求,跨域XHR对象也有一些限制,如下限制:
不能使用setRequestHeader()设置自定义头部;
不能发送和接收cookie。
调用getAllResponseHeaders()方法总会返回空字符串。
跨浏览器的CORS的实现
如上介绍的是对IE下和标准浏览器下2种方案实现跨域的实现方案,下面我们可以来封装下对常用的所有浏览器支持下,首先我们先检查是否存在withCredentials属性(标准浏览器下有这个属性),再结合检测XDomainRequest对象是否存在(就可以检测到IE),如下是所有封装的代码:
function createCORSRequest(method,url) {
var xhr = new XMLHttpRequest();
if("withCredentials" in xhr) {
xhr.open(method,url,true);
}else if(typeof XDomainRequest != 'undefined') {
xhr = new XDomainRequest();
xhr.open(method,url);
xhr = null;
var request = createCORSRequest('POST',"/ajax/ajax.php");
if(request) {
request.onload = function(){
alert(request.responseText);
request.send();
浏览器支持程度:IE7+,firefox3.5+,safari4+,chrome3+等;
JSONP跨域技术的基本原理
Jsonp跨域get请求是如何实现的;我们先来了解下为什么会出现跨域?
Javascript是一种在web开发中经常使用的前端动态脚本技术,在javascript中,有一个很重要的安全限制,被称为”same-Origin-Policy”同源策略,这一策略对于javascript代码能够访问的页面内容作了很重要的限制,即javascript只能访问与包含它的文档在同一域下的内容;
JSONP的基本原理是:利用在页面中创建&script&节点的方法向不同域提交http请求的方法称为JSONP。
比如我现在的ajax.html页面& 下提交ajax请求 get请求,我们可以在ajax.html页面动态的创建script标签,如下:
var eleScript= document.createElement("script");
eleScript.type = "text/javascript";
eleScript.src = "/ajax/ajax.php";
document.getElementsByTagName("HEAD")[0].appendChild(eleScript);
当get请求从 返回时,可以返回一断javascript代码,这段代码会自动执行,可以用来负责调用页面 中的一个callback函数;
理解JSONP执行过程如下:
首先在客户端注册一个callback(比如jsonpcallback),然后把callback名字(比如叫jsonp123456)传给服务器端,服务器端得到callback名字后,需要用jsonp123456()把将要输出的json内容包括起来,此时,服务器生成的json数据才能被客户端正确接收;然后以javascript语法的方式,生成一个function,function的名字就是传递回来的参数jsonp123456.然后就可以在客户端直接运行调用jsonp123456这个函数了;
JSONP的优点:它不像XMLHttpRequest对象实现ajax请求受到同源策略的限制,它在所有的浏览器都支持,比如古老的IE6也支持,并且在请求完成后可以通过callback的方式传回结果;
JSONP的缺点:只支持get请求,不支持post请求,它只支持http跨域的请求情况,不能解决不同域的两个页面之间如何进行javascript调用的问题;
阅读(...) 评论()

我要回帖

更多关于 ajax封装函数 的文章

 

随机推荐