封装 AJAX
AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。对于前端初学者来说,封装一个 AJAX 函数是非常有必要的,能够大大减少代码量。
基本代码
/**
* ajax函数
* @param {object} opt
*/
function ajax(opt = {}) {
//强制opt为对象
opt = opt || {};
//http连接的方式
opt.method = opt.method || 'POST';
//发送请求的url
opt.url = opt.url || '';
//是否为异步请求,true为异步的,false为同步的
opt.async = opt.async || true;
//发送的参数,类型为对象类型
opt.data = opt.data || null;
//预期服务器返回数据类型
opt.dataType = opt.dataType || 'JSON';
//ajax发送并接收成功调用的回调函数
opt.success = opt.success || function() {};
//ajax发送并接收失败调用的回调函数
opt.error = opt.error || function() {};
let xhr = null;
if (window.XMLHttpRequest) {
// IE7+, Firefox, Chrome, Opera, Safari 代码
xhr = new XMLHttpRequest();
//针对某些特定版本的mozilla浏览器的bug进行修正。
if (xhr.overrideMimeType) {
xhr.overrideMimeType('text/xml');
}
} else {
// IE6, IE5 代码
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
let params = [];
// Object.keys(opt.data).forEach(key => { params.push(key + '=' + opt.data[key]) });
for (let key in opt.data) params.push(key + '=' + opt.data[key]);
let postData = params.join('&');
//跨域请求
if (opt.dataType === 'JSONP') {
creatScript(opt.url, postData);
} else {
if (opt.method.toUpperCase() === 'POST') {
xhr.open(opt.method, opt.url, opt.async);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8');
xhr.send(postData);
// xhr.setRequestHeader('Content-Type', 'application/json');
// xhr.send(JSON.stringify(data));
} else if (opt.method.toUpperCase() === 'GET') {
if (postData.length > 0) {
xhr.open(opt.method, opt.url + '?' + postData, opt.async);
} else {
xhr.open(opt.method, opt.url, opt.async);
}
xhr.send(null);
}
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE) {
// 信息响应(100–199),成功响应(200–299),重定向(300–399),客户端错误(400–499)和服务器错误 (500–599)
if (xhr.status >= 200 && xhr.status < 400) {
opt.success(xhr.response);
} else if (xhr.status >= 400) {
opt.error(xhr.status);
}
};
}
}
}
当浏览器向服务端发送请求时,会时常碰到跨域问题。跨域是违反了浏览器的同源策略。
同源策略,它是由Netscape提出的一个著名的安全策略,现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指:域名,协议,端口相同。有一者不同都是违反同源策略。
我们可以使用 JSONP 的方式来解决跨域问题
JSONP 原理:
(1)前端事先定义了一个解析函数,是一个回调函数;
(2)但数据在服务端,客户端会把这个函数包装成参数传递给后端;
(3)服务端获取到该函数,把要返回的数据作为该函数参数并调用;
(4)前端接受到后,JS 引擎会执行该回调函数了,拿到后端传递的数据。
/**
* 动态创建script标签
* --------------------------------------------
*
*
* @param {string} url 发送请求的url
* @param {object} data 发送的参数
*/
function creatScript(url, data) {
//应用搜索接口
//JSONP get请求
//利用script标签的src属性没有同源策略限制这一特点,访问非同源数据
let oScript = document.createElement('script');
//回调函数名jsonp,远程服务上调用这个函数并且将JSON 数据形式作为参数传递,完成回调
oScript.src = url + '?' + data + '&callback=jsonp';
document.body.appendChild(oScript);
}