## 问题 Problem
你想不借助jQuery,使用AJAX从服务器上下载数据。
You want to load data from your server via AJAX without using the jQuery library.
## 方法 Solution
你可以使用原生的[XMLHttpRequest](http://en.wikipedia.org/wiki/XMLHttpRequest)对象。
You will use the native [XMLHttpRequest](http://en.wikipedia.org/wiki/XMLHttpRequest) object.
我们搭建一个简单的页面,该页面上有一个按钮。
Let’s set up a simple test HTML page with a button.
~~~
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>XMLHttpRequest Tester</title>
</head>
<body>
<h1>XMLHttpRequest Tester</h1>
<button id="loadDataButton">Load Data</button>
<script type="text/javascript" src="XMLHttpRequest.js"></script>
</body>
</html>
~~~
当按钮被点击时,我们希望可以给服务器发送一个Ajax请求,获取一些数据。为此,我们使用了一个很小的JSON文件。
When the button is clicked, we want to send an Ajax request to the server to retrieve some data. For this sample, we have a small JSON file.
~~~
// data.json
{
message: "Hello World"
}
~~~
下一步,创建一个CoffeeScript文件来处理页面逻辑。本文件中的代码创建了一个函数,当Load Data按钮被点击时调用它。
Next, create the CoffeeScript file to hold the page logic. The code in this file creates a function to be called when the Load Data button is clicked.
~~~
1 # XMLHttpRequest.coffee
2 loadDataFromServer = ->
3 req = new XMLHttpRequest()
4
5 req.addEventListener 'readystatechange', ->
6 if req.readyState is 4 # ReadyState Compelte
7 if req.status is 200 or req.status is 304 # Success result codes
8 data = eval '(' + req.responseText + ')'
9 console.log 'data message: ', data.message
10 else
11 console.log 'Error loading data...'
12
13 req.open 'GET', 'data.json', false
14 req.send()
15
16 loadDataButton = document.getElementById 'loadDataButton'
17 loadDataButton.addEventListener 'click', loadDataFromServer, false
~~~
## 讨论 Discussion
在上面的代码中,我们本质上是获取了一个HTML中(16行)的按钮的一个句柄,添加了一个_click_事件监听器(17行)。在我们的事件监听器中,吧我们的回调函数定义为loadDataFromServer。
In the above code we essentially grab a handle to the button in our HTML (line 16) and add a _click_ event listener (line 17). In our event listener, we define our callback function as loadDataFromServer.
我们在第2行那里定义了我们的loadDataFromServer回调函数。
We define our loadDataFromServer callback beginning on line 2.
我们创建了一个XMLHttpRequest请求对象(3行),并添加了一个_readystatechange_事件处理器。只要请求对象的readystate发生变化,该事件处理器就会被触发。
We create a XMLHttpRequest request object (line 3) and add a_readystatechange_ event handler. This fires whenever the request’s readyState changes.
在事件处理器中,我们检查readyState是否等于4,即表明请求已经完成。然后,我们再查看请求的状态值,状态码为200或者304都代表这是一次成功的请求。其他状态码都表示请求出错。
In the event handler we check to see if the readyState = 4, indicating the request has completed. Then, we check the request status value. Both 200 or 304 represent a succsessful request. Anything else represents an error condition.
如果请求确实成功了,我们会对从服务器端返回来的JSON进行求值,然后把其赋值给一个数据变量。这个时候,我们就可以随心所欲地使用返回的数据了。
If the request was indeed successful, we eval the JSON returned from the server and assign it to a data variable. At this point, we can use the returned data in any way we need to.
最后一件要做的事情就是把我们的请求发出去。
The last thing we need to do is actually make our request.
13行,打开一个’GET’请求,来获取data.json文件。
Line 13 opens a ‘GET’ request to retreive the data.json file.
14行,把请求发给服务器。
Line 14 sends our request to the server.
## 支持老掉牙的浏览器 Older Browser Support
如果你的程序需要支持老版本的Internet Explorer,你需要确保XMLHttpRequest对象是否存在。做法就是在创建XMLHttpRequest实例之前,先包含下面这段代码。
If your application needs to target older versions of Internet Explorer, you will need to ensure the XMLHttpRequest object exists. You can do this by including this code before creating the XMLHttpRequest instance.
~~~
if (typeof @XMLHttpRequest == "undefined")
console.log 'XMLHttpRequest is undefined'
@XMLHttpRequest = ->
try
return new ActiveXObject("Msxml2.XMLHTTP.6.0")
catch error
try
return new ActiveXObject("Msxml2.XMLHTTP.3.0")
catch error
try
return new ActiveXObject("Microsoft.XMLHTTP")
catch error
throw new Error("This browser does not support XMLHttpRequest.")
~~~
这段代码用来保证在全局作用域内存在XMLHttpRequest对象。
This code ensures the XMLHttpRequest object is available in the global namespace.
- 贡献
- 作者
- 授权协议
- 1、Syntax
- 在服务端和客户端重用代码
- For循环
- 嵌入JavaScript代码
- 值域
- 2、Classes and Objects
- 类方法和实例方法
- CoffeeScript式的Type函数
- 链式调用
- 克隆对象(深度克隆)
- 不存在就赋值为对象字面量
- 类变量
- 3、Strings
- 分割字符串
- 字符串匹配
- 查找子字符串
- 让整个字符串小写
- 大写整个字符
- 去掉字符串首尾的空白
- 生成唯一的ID
- 首字母大写
- 重复字符串
- 字符串插值
- 4、Arrays
- Python式的Zip函数 Python-like Zip Function
- 数组去重 Removing Duplicate Elements from Arrays
- 基于数组构建字典对象 Creating a dictionary Object from an Array
- 数组转成字符串 Creating a String from an Array
- 检查每一个元素 Testing Every Element
- 数组最大值
- 过滤数组 Filtering Arrays
- 定义区间数组 Define Ranges Array
- 转置数组 Reversing Arrays
- 化简数组 Reducing Arrays
- 使用数组来做值交换 Using Arrays to Swap Variables
- 列表解析 List Comprehensions
- 检查值的类型是否是数组
- 连接数组
- 搅乱数组中的元素 Shuffling Array Elements
- 数组映射 Mapping Arrays
- 5、Dates and Times
- Calculate Phase of the Moon for a Date
- 找出某月的最后一天是几号 Finding the Last Day of the Month
- 获取两个日期相差的天数 Get Days Between Two Dates
- 计算复活节岛日期 Calculate the Date of Easter Sunday
- 计算感恩节的日期(美国和加拿大) Calculate the Date of Thanksgiving (USA and Canada)
- 计算上一个(下一个)月份 Finding Last (or Next) Month
- 6、Math
- 快速逆平方根
- 一个随机整数的函数
- 更快的斐波那契算法
- 生成可预测的随机数
- 弧度与度转换
- 生成随机数
- 数学常数
- 7、Functions
- 反抖动函数 Debounce Functions
- 参数数组化 Splat Arguments
- 当函数调用的括号不可以省略时 When Function Parentheses Are Not Optional
- 递归函数 Recursive Functions
- 8、Metaprogramming
- 扩展内置对象 Extending Built-in Objects
- 检测并创建缺失的函数 Detecting and Creating Missing Functions
- 9、jQuery
- 回调绑定
- 创建jQuery插件
- AJAX
- 10、Ajax
- 不依赖jQuery的Ajax请求 Ajax Request Without jQuery
- 11、Regular Expressions
- 替换子字符串 Replacing Substrings
- 使用定点 Using Heregexes
- 使用HTML字符实体替换HTML标签 Replacing HTML Tags with HTML Named Entities
- 搜索子字符串 Searching for Substrings
- 12、Networking
- 简单的服务器
- 双向客户端
- 最简单的HTTP客户端
- 最简单的HTTP服务器
- 简单的客户端
- 双向服务端 Bi-Directional Server
- 13、Design Patterns
- 命令模式
- 单例模式
- 策略模式 Strategy Pattern
- 建造者模式 Builder Pattern
- 备忘录模式 Memento Pattern
- 解释器模式 Interpreter Pattern
- 装饰者模式
- 桥接模式
- 工厂方法模式
- 14、Databases
- MongoDB
- SQLite
- 15、Testing
- 使用Jasmine测试