比较常见的请求方式有GET和POST,下面对这两种方式做详细介绍
GET请求
GET请求常用于向服务器获取数据,发送请求时,参数被追加到URL的末尾。参数以问号开始,名和值之间用等号链接,名值对之间用和号(&)分隔。使用GET方式发送的数据常被称作查询字符串
xhr.open('GET', 'https://www.86886.wang/api/articles?limit=10&page=1', true);
编码
由于URL无法识别特殊字符,所以如果数据中包含特殊字符(如中文),则需要使用encodeURIComponent()进行编码
缓存
在GET请求中,为了避免缓存的影响,可以向URL添加一个随机数或时间戳
下面是一个完整的GET请求封装示例
<div id="result"></div>
<button id="btn">GET异步请求</button>
<script>
var url = 'https://www.86886.wang/api/articles';
var data = {limit: 1, page: 1};
var callback = function(data) { result.innerHTML = data; }
btn.onclick = function() {
getData(url, data, callback);
}
function getData(url, data, callback) {
var xhr = new XMLHttpRequest();
// 异步请求
xhr.onreadystatechange = function() {
if(xhr.readyState == 4) {
if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
callback && callback(xhr.responseText);
}
}
}
// 特殊字符编码
for(var key in data) {
url += (url.indexOf("?") == -1 ? "?" : "&");
url += encodeURIComponent(key) + "=" + encodeURIComponent(data[key]);
}
url += '&' + Date.now(); // 随机时间戳,防止请求缓存
xhr.open('GET', url, true);
xhr.send();
}
</script>
POST请求
POST请求常用于向服务器提交数据,它会把数据作为请求的主体提交,POST请求的主体可以包含非常多的数据,而且格式不限。
设置请求头
调用xhr.open()方法后,第二步是设置请求头,通常会把Content-Type
设置成application/x-www-form-urlencoded
,也就是表单提交时的内容类型
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
随着前后端分离开发的发展,如果不是提交图片或文件类型的数据,Content-Type
设置为application/json
更常用
如果多次调用setReQuestHeader(),这些值会被依次添加到请求头中,即使设置的值是相同的
发送主体
POST数据的格式与查询字符串格式相同,名和值之间用等号链接,名值对之间用和号(&)分隔。最后拼接成一个字符串,并使用send()方法发送
xhr.send('name="wmui"&age=18');
编码和缓存
由于使用POST方式传递数据时,需要设置请求头"Content-Type",这一步骤能够自动对特殊字符(如中文)进行编码,所以就不再需要使用encodeURIComponent()方法了
POST请求主要用于数据提交,相同URL的重复POST请求从服务器得到的响应可能不同,所以不应该缓存使用POST方法的请求
下面是一个POST请求的封装示例
<div id="result"></div>
<button id="btn">POST异步提交</button>
<script>
var url = 'https://www.86886.wang/api/article';
var params = {title: 'test', content: 'good'};
var callback = function(data) { result.innerHTML = data; }
var token = 'asdfg';
// 发布文章
btn.onclick = function() {
postData(url, params, callback, token);
}
function postData(url, data, callback, token) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState == 4) {
if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
callback && callback(xhr.responseText);
}
}
}
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-Type','application/json');
if(token) {xhr.setRequestHeader('Token', token)};
xhr.send(JSON.stringify(data)); // 必须是字符串形式
}
</script>
封装
把GET请求和POST请求完整的封装为AJAX函数
function AJAX(obj) {
var method = obj.method || 'GET',
headers = obj.headers || {},
data = obj.data || {},
url = obj.url || '';
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState == 4) {
if((xhr.status >= 200 && xhr.readyState < 300) || xhr.status == 304) {
obj.callback && obj.callback(xhr.responseText)
}
}
}
if((obj.method).toUpperCase() == 'GET') {
// 编码
for(var key in data) {
url += (url.indexOf("?") == -1 ? "?" : "&");
url += encodeURIComponent(key) + "=" + encodeURIComponent(data[key]);
}
// url += '&' + Date.now(); // 随机时间戳,防止请求缓存
}
xhr.open(method, url, true);
// 设置header
for(var header in headers) {
xhr.setRequestHeader(header, headers[header]);
}
if((obj.method).toUpperCase() == 'GET') {
xhr.send(null);
}else{
xhr.send(JSON.stringify(data));
}
}
使用示例
<div id="result"></div>
<button id="btn">POST异步提交</button>
<script>
btn.onclick = function() {
AJAX({
url: 'https://www.86886.wang/api/article',
method: 'POST',
data: {
title: 'hello',
content: 'hello'
},
headers: {
'Token': 'asdf',
'Content-Type': 'application/json'
},
callback: function(ret) {
result.innerHTML = ret
}
})
}
</script>
重点说明:get请求的参数默认是不会对中文进行编码的,要开发者手动编码;post请求浏览器会自动进行编码。