【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
今天决定学习一下Ajax异步的XMLHttpRequest对象,平时一直使用jQuery.ajax()就万事大吉,
当自己要实现一套时才发现当中的细节事情!jQuery源码真的博大精深优美得很;
先从w3cschool看一下基本的使用方式,参考的jQ版本是v1.11.1
http://www.w3school.com.cn/xml/xml_http.asp
基本流程是先做简单XMLHttpRequest兼容处理,提交请求,最后是回调处理结果;
setup1 配置
开始时候在想怎样才能写出优美的参数传值,看jQ源码发现是使用jQuery.extend,而且这函数在很多地方都在应用,看来分量很重噢;
手册介绍是用一个或多个其他对象来扩展一个对象,返回被扩展的对象;如果不指定target,则给jQuery命名空间本身进行扩展。
jQ是先定义了基本参数对象ajaxSettings#8830行开始;然后调用ajaxSetup方法,其实这货还是调用了jQuery.extend去合并对象;只是判断是否是扩展配置对象;
自己太赖了只做最简参数单合并和获取回调方法事情;
function ajaxSetup(opations) {
if (typeof opations == 'object') {
for (key in opations) {
//Code....
}
}
return ajaxSetting;
}
setup2
实例化XMLHttpRequest就交由两个方法isWindowXHR和isIEXHR,然后由JS自行判断使用哪一个;
这里基本没什么特别!jQuery基本也是这么干的!只是它还做了很多IE6~9的浏览器兼容代码(难关jQ2就放弃治疗它们)
// Create the request object
// (This is still attached to ajaxSettings for backward compatibility)
jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?
// Support: IE6+
function() {
// XHR cannot access local files, always use ActiveX for that case
return !this.isLocal &&
// Support: IE7-8
// oldIE XHR does not support non-RFC2616 methods (#13240)
// See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx
// and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9
// Although this check for six methods instead of eight
// since IE also does not support "trace" and "connect"
/^(get|post|head|put|delete|options)$/i.test( this.type ) &&
createStandardXHR() || createActiveXHR();
} :
// For all other browsers, use the standard XMLHttpRequest object
createStandardXHR;
我万恶地几行没养分的代码就好了!
var xmlHttp = isWindowXHR() || isIEXHR();
function isWindowXHR() {
//Code....
}
function isIEXHR() {
//Code....
}
setup3 传值请求服务器和处理回调
这里jQ做了很多参数值的过滤、是否是跨域请求、head部分组装,是否跨域分开了好像是两部分处理(不知道有没有看错!代码太长了)
搜源码jQuery.ajaxTransport可以找到;
然后也是跟XMLHttpRequest流程定义调用send处理onreadystatechange在不同状态触发事件;
//TODO:增加其他状态处理
function stateChange() {
if (xmlHttp.readyState == 4) {
//Code....
}
}
return {
'ajax' : function(opations) {
var settings = ajaxSetup(opations);
if (xmlHttp !== null && settings) {
xmlHttp.onreadystatechange = stateChange;
switch(settings['type'].toUpperCase())
{
case 'POST':
//Code....
break;
case 'GET':
//Code....
break;
}
} else {
alert("Your browser does not support XMLHTTP.");
}
}
};
在这次学习中发现一个很好的网站
whatwg.org
后来发现这家伙跟W3C是很有冤缘;
详细看这里《哪个HTML5?WHATWG与W3C或分道扬镳》
http://www.cnblogs.com/xesam/archive/2012/07/23/2604254.html
完整代码:
index.html
<DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript" src="xhr.js"></script>
</head>
<body>
<input type="button" id="gTime" value="获取服务器时间" />
<div id="serTime">00:00:00</div>
</body>
</html>
<script type="text/javascript">
gTime.addEventListener("click", function(){
$.ajax({
type: "POST",
url: "xmlHttpRequestAction.php",
dataType : 'json',
async : true,
data: "name=John&location=Boston",
success : function(msg) {
var obj = eval('(' + msg + ')');
serTime.childNodes[0].nodeValue = obj.date;
console.log(obj);
}
});
}, false);
</script>
xhr.js
var $ = (function(Global){
var xmlHttp = isWindowXHR() || isIEXHR();
var callback = {};
var ajaxSetting = {
//TODO:过滤地址符号,例如结尾的"/"
'url' : location.href,
'type' : 'GET',
//TODO:增加类型转换判断
'dataType' : 'text',
'async' : true,
//TODO:增加支持对象类型
'data' : null
};
function isWindowXHR() {
try {
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
}
} catch (e) {}
}
function isIEXHR() {
try {
if (window.ActiveXObject) {
return new ActiveXObject("Microsoft.XMLHTTP");
}
} catch (e) {}
}
function ajaxSetup(opations) {
if (typeof opations == 'object') {
for (key in opations) {
if (typeof ajaxSetting[key] !== 'undefined') {
ajaxSetting[key] = opations[key];
} else {
switch(typeof opations[key])
{
case 'function':
callback[key] = opations[key];
break;
}
}
}
}
return ajaxSetting;
}
//TODO:增加其他状态处理
function stateChange() {
if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200) {
if (callback.success) {
//Success
return callback.success(xmlHttp.responseText);
} else {
return xmlHttp.response;
}
} else {
alert("Problem retrieving XML data");
}
}
}
/* https://xhr.spec.whatwg.org/ */
return {
'ajax' : function(opations) {
var settings = ajaxSetup(opations);
if (xmlHttp !== null && settings) {
xmlHttp.onreadystatechange = stateChange;
switch(settings['type'].toUpperCase())
{
case 'POST':
xmlHttp.open('POST', settings['url'], settings['async']);
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
xmlHttp.send(ajaxSetting['data']);
break;
case 'GET':
settings['url'] += ('?' + ajaxSetting['data']);
xmlHttp.open('GET', settings['url'], settings['async']);
xmlHttp.send(null);
break;
}
} else {
alert("Your browser does not support XMLHTTP.");
}
}
};
})(window);
xmlHttpRequestAction.php
<?php
date_default_timezone_set("PRC");
echo json_encode(array('date'=>date('Y-m-d h:i:s'),'POST'=>$_POST,'GET'=>$_GET, 'content'=>'中文'));
?>
来源:oschina
链接:https://my.oschina.net/u/4731/blog/342073