一、實例化 XMLHttpRequest 對象
使用 Ajax API 的第一件事情就是實例化 XMLHttpRequest 對象。
var xhr = new XMLHttpRequest();
二、初始化請求
使用 XMLHttpRequest 對象時,要調用的第一個方法就是 open()
。它不會真正發送請求,而只是初始化一個請求准備發送。
open()
方法接受三個參數:請求的類型(“GET”、“POST”等)、請求的資源地址和表示是否發送異步請求的布爾值(默認為 true
)。
xhr.open('GET', 'example.php', false);
啟動一個同步 GET 請求,請求的資源地址為 example.php
。
三、發送請求
xhr.send(null);
send()
方法接受一個參數,表示發送的請求主體數據。如果不需要發送請求主體數據,則必須輸入 null
,因為這個參數對有些瀏覽器來說是必需的。
四、GET 請求
HTML 代碼:
<div class="content"></div>
JavaScript 腳本:
var xhr = new XMLHttpRequest();
function addURLParam(url, name, value) {
url += (url.indexOf('?') == -1 ? '?' : '&');
url += encodeURIComponent(name) + '=' + encodeURIComponent(value);
return url;
}
xhr.onreadystatechange = function(){
if (xhr.readyState === 4) {
if (xhr.status === 200) {
document.querySelector('.content').innerHTML = xhr.responseText;
} else {
console.error(xhr.statusText);
}
}
};
xhr.onerror = function (e) {
console.error(xhr.statusText);
};
var url = 'server.php';
url = addURLParam(url, 'author', '張寶');
url = addURLParam(url, 'article', 'XMLHttpRequest API 使用指南');
xhr.open('GET', url, true);
xhr.send(null);
PHP 處理腳本:
if (isset($_GET["author"]) && isset($_GET["article"])) {
echo "GET:《" . $_GET["article"] . "》 by " . $_GET["author"];
}
五、POST 請求
POST 請求把數據作為請求主體提交。
5.1 使用序列化數據
HTML 代碼:
<div class="content"></div>
JavaScript 腳本:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (xhr.readyState === 4) {
if (xhr.status === 200) {
document.querySelector('.content').innerHTML = xhr.responseText;
} else {
console.error(xhr.statusText);
}
}
};
xhr.onerror = function (e) {
console.error(xhr.statusText);
};
var url = '../asset/source/server.php';
xhr.open('POST', url);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send("foo=bar&lorem=ipsum");
PHP 處理腳本:
if (isset($_POST["foo"]) && isset($_POST["lorem"])) {
echo "POST: foo=" . $_POST["foo"] . "&lorem=" . $_POST["lorem"];
}
5.2 使用序列化后的表單數據
HTML 代碼:
<div class="content">
<form id="postForm">
<input type="text" value="bar" name="foo"><input type="text" value="ipsum" name="lorem">
</form>
</div>
JavaScript 腳本:
var xhr = new XMLHttpRequest();
function serialize(form) {
var parts = [],
field = null,
i,
len,
j,
optLen,
option,
optValue;
for (i = 0, len = form.elements.length; i < len; i++) {
field = form.elements[i];
switch (field.type) {
case 'select-one':
case 'select-multiple':
if (field.name.length) {
for (j = 0, optLen = field.options.length; j < optLen; j++) {
option = field.options[j];
if (option.selected) {
optValue = '';
if (option.hasAttribute) {
optValue = (option.hasAttribute('value') ?
option.value : option.text);
} else {
optValue = (option.attributes['value'].specified ?
option.value : option.text);
}
parts.push(encodeURIComponent(field.name) + '=' +
encodeURIComponent(optValue));
}
}
}
break;
case undefined:
case 'file':
case 'submit':
case 'reset':
case 'button':
break;
case 'radio':
case 'checkbox':
if (field.checked) {
break;
}
default:
if (field.name.length) {
parts.push(encodeURIComponent(field.name) + '=' +
encodeURIComponent(field.value));
}
}
}
return parts.join('&');
}
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
document.querySelector('.content').innerHTML = xhr.responseText;
} else {
console.error(xhr.statusText);
}
}
};
xhr.onerror = function (e) {
console.error(xhr.statusText);
};
var url = 'server.php';
xhr.open('POST', url);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(serialize(document.getElementById('postForm')));
PHP 處理腳本:
if (isset($_POST["foo"]) && isset($_POST["lorem"])) {
echo "POST: foo=" . $_POST["foo"] . "&lorem=" . $_POST["lorem"];
}
六、FormData
類型
FormData 類型可以用於構造表單數據。
var formData = new FormData();
formData.append('username', '張三');
formData.append('email', 'zhangsan@example.com');
formData.append('birthDate', 1940);
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (xhr.readyState === 4) {
if (xhr.status === 200) {
document.querySelector('.content').innerHTML = xhr.responseText;
} else {
console.error(xhr.statusText);
}
}
};
xhr.open("POST", "server.php");
xhr.send(formData);
PHP 處理腳本:
if (isset($_POST["username"]) && isset($_POST["email"]) && isset($_POST["birthDate"])) {
echo "POST: username=" . $_POST["username"] . "&email=" . $_POST["email"] . "&birthDate=" . $_POST["birthDate"];
}
七、上傳文件
HTML 代碼:
<form action="uploadFiles.php" method="post" enctype="multipart/form-data">
<label for="file">文件名:</label>
<input type="file" name="images[]" multiple>
</form><hr>
<div class="content"></div>
JavaScript 代碼:
function uploadFiles(url, files) {
var formData = new FormData();
for (var i = 0, file; file = files[i]; ++i) {
formData.append('images[]', file); // 有可選的第三個參數,指定上傳文件的文件名
}
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.onload = function(e) {
document.querySelector('.content').innerHTML = xhr.responseText;
};
xhr.send(formData);
}
document.querySelector('input[type="file"]').addEventListener('change', function(e) {
uploadFiles('../asset/source/uploadFiles.php', this.files);
}, false);
PHP 服務器處理腳本(在與腳本同級的目錄下,新建文件夾 uploads
,作為保存上傳文件的地方):
for($i = 0; $i< count($_FILES['images']['name']); $i++) {
if ($_FILES['images']["error"][$i] > 0) {
switch($_FILES['images']["error"][$i]) {
case 1:
$err_info="上傳的文件超過了 php.ini 中 upload_max_filesize 選項限制的值";
break;
case 2:
$err_info="上傳文件的大小超過了 HTML 表單中 MAX_FILE_SIZE 選項指定的值";
break;
case 3:
$err_info="文件只有部分被上傳";
break;
case 4:
$err_info="沒有文件被上傳";
break;
case 6:
$err_info="找不到臨時文件夾";
break;
case 7:
$err_info="文件寫入失敗";
break;
default:
$err_info="未知的上傳錯誤";
break;
}
echo "錯誤:" . $err_info . "<hr>";
continue;
}
echo "上傳文件名: " . $_FILES['images']["name"][$i] . "<br>";
echo "文件類型: " . $_FILES['images']["type"][$i] . "<br>";
echo "文件大小: " . ($_FILES['images']["size"][$i] / 1024) . " kB<br>";
echo "文件臨時存儲的位置: " . $_FILES['images']["tmp_name"][$i];
echo "<hr>";
$tmpFilePath = $_FILES['images']['tmp_name'][$i];
if ($tmpFilePath != "") {
$newFilePath = "./uploads/" . $_FILES['images']['name'][$i];
move_uploaded_file($tmpFilePath, $newFilePath);
}
}
(完)