HTTP定義POST來發送資料給伺服器,POST適用於非等冪操作,POST有可能會改變伺服端的狀態,像是修改資料庫的內容,或在伺服器上儲存檔案等。
如果要發送POST,則可以在非同步物件open()時,將第一個參數設為'POST',之後使用setRequestHeader()設定內容類型,因為POST要發送的資料會放在請求的本體中,所以你必須告知發送的資料類型為何,接著在send()時,將要發送的資料,作為send()的引數傳入。
例如,若發送表單類型資料,必須設置請求標頭'Content-Type'為'application/x-www-form-urlencoded',以下是個示範:
...
var url = 'somewhere';
var queryString = 'a=10&b=20';
xmlHttp.open('POST', url);
xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlHttp.send(queryString);
var url = 'somewhere';
var queryString = 'a=10&b=20';
xmlHttp.open('POST', url);
xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlHttp.send(queryString);
放在POST本體中的資料,也有可能是其它格式,例如XML或JSON,你必須設定不同的請求標頭,這在之後還會說明。
在下面這個例子中,將先前對非同步物件的基本操作進行了簡單的封裝,並使用POST來作 使用 GET 請求 中第二個範例。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Strict//EN">
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<script type="text/javascript">
window.onload = function() {
var xhr = window.XMLHttpRequest &&
(window.location.protocol !== 'file:'
|| !window.ActiveXObject) ?
function() {
return new XMLHttpRequest();
} :
function() {
try {
return new ActiveXObject('Microsoft.XMLHTTP');
} catch(e) {
throw new Error('XMLHttpRequest not supported');
}
};
function param(obj) {
var pairs = [];
for(var name in obj) {
var pair = encodeURIComponent(name) + '=' +
encodeURIComponent(obj[name]);
pairs.push(pair.replace('/%20/g', '+'));
}
return pairs.join('&');
}
function ajax(option) {
option.type = option.type || 'GET';
option.header = option.header || {
'Content-Type':'application/x-www-form-urlencoded'};
option.callback = option.callback || function() {};
// 沒有 url,啥事也作不了
if(!option.url) {
return;
}
var request = xhr();
request.onreadystatechange = function() {
option.callback.call(request, request);
};
var body = null;
var url = option.url;
if(option.data) {
if(option.type === 'POST') {
body = param(option.data);
}
else {
url = option.url + '?' + param(option.data)
+ '&time=' + new Date().getTime();
}
}
request.open(option.type, url);
for(var name in option.header) {
request.setRequestHeader(
name, option.header[name]);
}
request.send(body);
}
document.getElementById('url').onblur = function() {
ajax({
type: 'POST',
url : 'POST-1.php',
data: {url : document.getElementById('url').value},
callback: function(request) {
if(request.readyState === 4) {
if(request.status === 200) {
var message = '';
if(request.responseText
=== 'urlExisted') {
message = 'URL 已存在';
}
document.getElementById('message')
.innerHTML = message;
}
}
}
});
};
};
</script>
</head>
<body>
新增書籤:<br>
網址:<input id="url" type="text">
<span id="message" style="color:red"></span><br>
名稱:<input type="text">
</body>
</html>
在上例中,呼叫ajax()時必須傳入選項物件,可使用的選項為:
- type指定請求類型,預設為'GET'
- url指定請求的URL
- data指定請求參數
- header指定請求標頭,預設'Content-Type'為'application/x-www-form-urlencoded'
- callback指定回呼函式,回呼函式的this與第一個參數會綁定為非同步物件(因為onreadystatechange設置的回呼函式中第一個參數,Firefox是傳入事件,Internet Explorer則無傳入任何東西,函式中的this,Firefox中是XMLHttpRequest,Internet Explorer中是window,因此這邊予以統一)