## 問題 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測試