原生XMLHttpRequest学习日志

今天决定学习一下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‘=>‘中文‘));
?>
时间: 2024-10-17 01:48:38

原生XMLHttpRequest学习日志的相关文章

JAVA学习日志——Ajax和Json

# JAVA学习日志--Ajax和Json # Ajax和Json在一个web项目中可以说是经常用到了,Ajax是一种用于创建快速动态网页的技术,而Json则是一种与语言无关的数据交换的格式.以下是个人在学习过程中的总结. 一.Ajax 1.同步与异步 在学习Ajax之前我们要先知道什么是同步,什么是异步. 同步现象:客户端发送请求到服务器端,当服务器返回响应之前,客户端都处于等待卡死状态. 异步现象:客户端发送请求到服务器端,无论服务器是否返回响应,客户端都可以随    意做其他事情,不会被卡

winform学习日志(二十三)---------------socket(TCP)发送文件

一:由于在上一个随笔的基础之上拓展的所以直接上代码,客户端: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Net.Sockets; using Sys

Linux学习日志2-vim使用基础

vim是linux操作系统下的一个文本编辑工具,功能非常强大,但刚学习起来比较复杂.vim的所有功能要讲明白得有几百页,在这里只是记录一下vim的一些基本用法. 首先vim打开文件的三种方式: vim +# xxx(#是数字):表示打开xxx文件并将光标定位到指定行. vim -o xx1 xx2 xx3:表示同时打开三个文件,垂直分割显示 vim -O xx1 xx2 xx3:表示同时打开三个文件,水平分割显示 多个文件间跳转:键入ctrl+w后:→向左.←向右.↑向上.↓向下 vim打开文件

Linux学习日志day1——无人值守系统安装DHCP+TFTP+PXE+Kickstar

Linux学习日志day1--无人值守批量系统远程网络安装(DHCP+TFTP+PXE+Kickstar)                                         --作者:江信瀚 服务器环境介绍: 主机名:workstation.example.com 关闭SElinux以及防火墙 虚拟机:VMware(关闭了VMware的DHCP服务) 网卡配置: 静态IP获取! IPV6全部都删除,因为根本用不到 子网IP可以在VMware中设置 8.8.8.8是谷歌的DNS服务器

Cocos2d-x 3.1.1 学习日志4--cocos2d-x解决中文乱码问题的几种办法

做个打飞机的游戏,由于版本太新,网上基本没有教教程,我的版本是cocos2d-x 3.1.1的,今天遇到cocos2dx中中文乱码的问题.无奈只好Google百度寻求答案,明白了这个问题的缘由.因为cocos2d-x内部是以utf8处理文本的,而VS直接输入时文本编码为GBK,如果添加L标志,则为Unicode编码. 解决这个问题有三种办法: 将源代码文件保存为utf8编码,不过由于编译器的问题,这种方式会导致很多无法预测的问题 将字符串用utf8编码集中存到一文件中,然后用代码读取这些字符串来

Cocos2d-x 3.1.1 学习日志3--C++ 初始化类的常量数据成员、静态数据成员、常量静态数据成员

有关const成员.static成员.const static成员的初始化: 1.const成员:只能在构造函数后的初始化列表中初始化 2.static成员:初始化在类外,且不加static修饰 3.const static成员:类只有唯一一份拷贝,且数值不能改变.因此,可以在类中声明处初始化,也可以像static在类外初始化 #include <iostream> using std::cout; using std::endl; class base { public: base(int

SQL 学习日志01

查看一个数据库的所有表: Select TABLE_NAME FROM 数据库名称.INFORMATION_SCHEMA.TABLES Where TABLE_TYPE='BASE TABLE' (select * from 表名 where 条件) 查看一张表的表结构: sp_help table_name(表名)  获取的信息比较全 sp_columns table_name(表名) 创建数据库: use master go create database test01(数据库名) 删除数据

SQL 学习日志02

SQL数据类型 1.字符类型 char   --定长字符数据   如 char(12)  这字段就会占用12字节的空间,无论这个字段只填写了2个字节.一般在可确定这字段长度时选用,如sex字段(因只有男和女两项可选)就可用 char(2). varvhar   --可变长字符数据  如varchar(50) 这字段最大只能填写50字节,按实际填写的字节存储.一般在不确定这字段长度时使用,如 Smail字段(因邮箱的长度不确定) 就可用varchar(50). text    --用来存储大量非统

Linux学习日志1-基本知识

1.冯.诺依曼体系计算机五大组成部件: 1.控制器:控制其他四个部件的运作 2.运算器:负责计算加减乘除 3.存储器:存放运算的数据来源与结果 4.输入设备:接收数据输入存入存储器 5.输出设备:从存储器接收数据输出 2.Linux的起源: 1991年一个芬兰大学生Linus Torvalds参考其老师的教学用操作系统Minix的思想(注意仅仅是思想),自己写了一个操作系统内核,命名为Linux 0.0.1,发布在comp.os.minix新闻组上,正式宣告Linux内核的诞生.从那时起,Lin