手动封装一个jQuery版的Ajax请求
jsonp原理:
- 判断是不是与当前页面是一个域 如果是一个域会正常发送ajax请求
- 如果不同域,会生成一个script标签生成一个随机的callback名
- 拼接url和callback 将其赋值给script的src
- 在全局中生成一个callback函数
var $ajax = function(obj) {
var url = obj.url;
var type = obj.type;
var dataType = obj.dataType;
var targetProtocol = ""; //目标接口的协议
var targetHost = ""; //目标接口的host,host是包涵域名和端口的
// 如果url不包含http 则为相对路径 一定同源
if (url.indexOf('http://') != -1 || url.indexof('https://') != -1) {
//包含时不一定是同源,后面再做判断
var TargetUrl = new URL(url); //url为字符串要转换
targetProtocol = TargetUrl.protocol;
targetHost = TargetUrl.host;
} else {
//不包含是一定同源 直接等于当前文件的端口和域名
targetProtocol = location.protocol;
targetHost = location.host;
}
if (dataType == 'jsonp') {
//同源,只能是
if (targetProtocol == location.protocol && targetHost == location.host) {
// console.log(123);
var xhr = null;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject("Microsoft.XMLHttp");
}
xhr.open(type, url, false);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var data = JSON.parse(xhr.responseText);
obj.success(data);
}
}
xhr.send(); //如果open第三个参数传true,或者不传,为异步模式。如果传false,为同步模式。
} else {
console.log(123);
//非同源 只能是get
// 随机生成一个callback函数
var callback = 'cd' + Math.floor(Math.random() * 10000000);
//在全局创建一个函数 callback 函数体为 success
window[callback] = obj.success;
//创建一个script标签
var script = document.createElement('script');
//将callback加在url,然后加到src中
if (url.indexOf('?') != -1) { //判断url之前有么参数
//有参数,前面不用加?
script.src = url + 'callback=' + callback;
} else {
//么有参数,加?
script.src = url + '?callback=' + callback;
}
//将标签加入body中
document.head.appendChild(script);
}
} else {
var xhr = null;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject("Microsoft.XMLHttp");
}
xhr.open(type, url, false);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var data = JSON.parse(xhr.responseText);
obj.success(data);
}
}
xhr.send(); //如果open第三个参数传true,或者不传,为异步模式。如果传false,为同步模式。
}
}