原生js实现Ajax,JSONP
Ajax内部的几个执行步骤
- 创建XMLHttpRequest对象(
new XMLHttpRequest()
) - 设置请求头(
setRequestHeader
) - 连接服务器(
open()
) - 设置回调(
onreadyStateChange
) - 发送数据(
send()
) - 在回调函数中获取数据
JSONP
利用script标签可以跨域请求资源解决跨域问题。详细解释可以看彻底弄懂跨域问题
前端代码
/* * 原生js实现Ajax * */ function Ajax(params) { params = params || {}; params.data = params.data || {}; var _json = params.jsonp ? jsonp(params): json(params); // 判断是json还是jsonp function json(params) { // 普通请求 params.type = (params.type || 'GET').toUpperCase(); // 设置请求默认类型 var urlData = formatParams(params.data); // 对数据进行格式化 var xhr = null; // 对xhr进行初始化 if (window.XMLHttpRequest) { xhr = new window.XMLHttpRequest(); } else { xhr = new ActiveXObject('Microsoft.XMLHTTP'); } var headers = params.headers || {}; if (params.type === 'GET') { xhr.open(params.type, params.url + '?' + urlData, true); setHeaders(xhr, headers); xhr.send(null); } else { xhr.open(params.type, params.url, true); setHeaders(xhr, headers); xhr.send(JSON.stringify(params.data)); } xhr.onreadystatechange = function () { if (xhr.readyState === 4) { var status = xhr.status; if (status >= 200 && status < 300) { var response = ''; var type = xhr.getResponseHeader('Content-Type'); if (type.indexOf('xml') !== -1 && xhr.responseXML) { // xml格式 response = xhr.responseXML; } else if (type.indexOf('application/json') !== -1) { // JSON格式 response = JSON.parse(xhr.responseText); } else { response = xhr.responseText; // 字符串格式 } params.success && params.success(response); } else { params.error && params.error(status); } } } } function jsonp(params) { var callbackName = params.jsonp; // 回调函数名 var head = document.getElementsByTagName('head')[0]; params.data['callback'] = callbackName; var data = formatParams(params.data); var script = document.createElement('script'); head.appendChild(script); // 创建jsonp函数,成功后自动让success函数调用,在自动删除 window[callbackName] = function (json) { // 设置回调,获取后台数据后才执行 head.removeChild(script); clearTimeout(script.timer); window[callbackName] = null; params.success && params.success(json); }; script.src = params.url + '?' + data; // 设置src的时候才开始向后台请求数据 if (params.time) { // 限定时间 script.timer = setTimeout(function () { window[callbackName] = null; head.removeChild(script); params.error && params.error({ message: '超时' }) }, params.time) } } function formatParams(data) { // 使用 encodeURIComponent 对 URI的某部分编码 var arr = []; for (var key in data) { arr.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key])); } // 添加随机数,防止缓存 arr.push('v=' + random()); return arr.join('&'); } function random() { return Math.floor(Math.random() * 10000 + 500); } function setHeaders(xhr, headers) { for (var key in headers) { xhr.setRequestHeader(key, headers[key]); } } }
使用方法
不用jsonp请求
Ajax({ url: '后端接口', type: 'POST', headers: { 'Content-Type': 'application/json', token: 'xxx' }, success(res) { console.log(res); }, error(status) { console.log(`some error status = ${status}`); } })
jsonp请求
Ajax({ url: 'http://localhost:8080', headers: { 'Content-Type': 'application/json' }, jsonp: 'getUser', time: 2000, success(res) { console.log(res); }, error(status) { console.log(`some error status = ${status.msg}`); } })
jsonp后台配置代码
var querystring = require('querystring'); var http = require('http'); var server = http.createServer(); server.on('request', function(req, res) { var params = querystring.parse(req.url.split('?')[1]); var fn = params.callback; // jsonp返回设置 res.writeHead(200, { 'Content-Type': 'text/javascript' }); var data = { user: 'xbc', password: '123456' } res.write(fn + '(' + JSON.stringify(data) + ')'); res.end(); }); server.listen('8080'); console.log('Server is running at port 8080...');
参考文章
相关推荐
fengchao000 2020-06-17
adonislu 2020-05-16
zmosquito 2020-05-10
adonislu 2020-05-10
somebodyoneday 2020-04-22
fengchao000 2020-04-22
fengchao000 2020-04-11
Richardxx 2020-03-07
somebodyoneday 2020-03-06
fengchao000 2020-03-05
somebodyoneday 2020-02-16
xiaouncle 2020-02-13
baijinswpu 2020-01-29
fengchao000 2020-01-10
fengchao000 2019-12-25
newthon 2019-12-23
somebodyoneday 2013-07-11