比较常见的请求方式有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请求浏览器会自动进行编码。