ajax回调函数版本
// 防抖
function antishake(func, wait) {
let timer = null
return function () {
clearTimeout(timer)
timer = setTimeout(() => {
func()
}, wait)
}
}
// 节流
function throttle(func,wait){
// let timer = null//节流阀
let flag = false
return function(){
if(flag) return// null====>false 如果是null(false)就执行下面代码(下面代码执行timer就变为true了),不是null就返回直接跳过 车上没人就上车 车上有人就直接跳过
flag = true
let timer = setTimeout(()=>{//上车了 车上有人
func() // 到站了
// timer = null // 下车
flag = false
},wait)
}
}
//兼容各大浏览器
function createXhr(){
if(window.XMLHttpRequest){
return new XMLHttpRequest()
}
return new ActiveXObject("Microsoft.XMLHTTP");//兼容ie6
}
function ajax(options){//option是一个对象
// 先准备默认的对象 存储默认值
let defaultObj = {
method:"GET",//默认为get请求
url: "",
aync:true,
data:"",
dataType: 'json',
callback(){}
}
// url地址没有传递或者传递的是空 直接返回出去
if(!options.url || options.url==""){
throw new Error('url地址必须不为空')
}
// 取出options里面的数据 给到defaultObj 给后面使用
for(let key in options){
defaultObj[key] = options[key]//将对应的key进行赋值
}
// 判断(验证)method
// defaultObj.method.toUpperCase()全字母转大写
// defaultObj.method.toLocaleUpperCase()首行转大写
if(defaultObj.method.toUpperCase() != "GET" && defaultObj.method.toUpperCase() != "POST"){
throw new Error("请求方式错误")
}
// 判断callback是否为函数
if(!typeof defaultObj.callback == "function"){
throw new Error("回调函数类型错误")
}
// 判断aync是否为boolean类型
if(!typeof defaultObj.aync == "boolean"){
throw new Error("aync必须是boolean类型")
}
// 如果是get请求 就对对应的数据和请求地址拼接
if(defaultObj.method.toUpperCase() == "GET"){
defaultObj.url+='?'+defaultObj.data
}
if(defaultObj.data.toString() == "[object Object]"){
let dataStr = ""
for(let key in defaultObj.data){
dataStr+=key+'='+defaultObj.data[key]+'&'
}
// 删除最后一个符号
dataStr = dataStr.slice(0,-1)
defaultObj.data = dataStr
}
// 创建一个请求对象
let xhr = createXhr()
// 设置open请求
xhr.open(defaultObj.method.toUpperCase(),defaultObj.url,defaultObj.aync)
// send发送请求
if(defaultObj.method.toUpperCase()=="POST"){
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
xhr.send(defaultObj.data)
}else{
xhr.send()
}
// 4、监听
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && /^20\d$/.test(xhr.status)) {
//5.接收响应
if(defaultObj.dataType == "json"){
let res = JSON.parse(xhr.responseText)//转化为json对象
defaultObj.callback(res)//回调,将对应响应结果带出
}else{
defaultObj.callback(xhr.responseText)//调用回调方法 将对应响应结果带出
}
}
}
}
jsonp回调函数版本
function jsonp(object){
// {链接地址,参数(对象),回调函数名字,回调函数}
let {url,params,callbackName,callback} = object
// 给window添加方法
// 随机生成一个函数名 不能重复
let fnName = "fn" + Date.now() + Math.ceil(Math.random()*10000)
// 将对应回调函数添加給window 添加的函数名随机
window[fnName] = callback
// 创建标签script
let script = document.createElement("script")
// 将方法名拼接到url地址后面 跨域执行xxx
url += `?${callbackName}=${fnName}`
// 将参数拼接
url += joinParams(params)
// 将这个url地址给到script标签的src属性(自带的属性)
script.src = url
// 将script加到body
document.body.appendChild(script)
// 判断是否已经加载成功,加载成功后就删除script节约空间
script.onload = function(){
script.remove()
delete window[fnName]
}
}
function joinParams(params){
let str = ''
// 取出对象的值
for(let key in params){
str+=`&${key}=${params[key]}`
}
return str
}
ajax promise版本(无回调函数)
// 防抖
function antishake(func, wait) {
let timer = null
return function () {
clearTimeout(timer)
timer = setTimeout(() => {
func()
}, wait)
}
}
// 节流
function throttle(func,wait){
// let timer = null//节流阀
let flag = false
return function(){
if(flag) return// null====>false 如果是null(false)就执行下面代码(下面代码执行timer就变为true了),不是null就返回直接跳过 车上没人就上车 车上有人就直接跳过
flag = true
let timer = setTimeout(()=>{//上车了 车上有人
func() // 到站了
// timer = null // 下车
flag = false
},wait)
}
}
//兼容各大浏览器
function createXhr(){
if(window.XMLHttpRequest){
return new XMLHttpRequest()
}
return new ActiveXObject("Microsoft.XMLHTTP");//兼容ie6
}
function ajax(options){//option是一个对象
// 先准备默认的对象 存储默认值
let defaultObj = {
method:"GET",//默认为get请求
url: "",
aync:true,
data:"",
dataType: 'json',
}
// url地址没有传递或者传递的是空 直接返回出去
if(!options.url || options.url==""){
throw new Error('url地址必须不为空')
}
// 取出options里面的数据 给到defaultObj 给后面使用
for(let key in options){
defaultObj[key] = options[key]//将对应的key进行赋值
}
// 判断(验证)method
// defaultObj.method.toUpperCase()全字母转大写
// defaultObj.method.toLocaleUpperCase()首行转大写
if(defaultObj.method.toUpperCase() != "GET" && defaultObj.method.toUpperCase() != "POST"){
throw new Error("请求方式错误")
}
// 判断callback是否为函数
if(!typeof defaultObj.callback == "function"){
throw new Error("回调函数类型错误")
}
// 判断aync是否为boolean类型
if(!typeof defaultObj.aync == "boolean"){
throw new Error("aync必须是boolean类型")
}
// 如果是get请求 就对对应的数据和请求地址拼接
if(defaultObj.method.toUpperCase() == "GET"){
defaultObj.url+='?'+defaultObj.data
}
if(defaultObj.data.toString() == "[object Object]"){
let dataStr = ""
for(let key in defaultObj.data){
dataStr+=key+'='+defaultObj.data[key]+'&'
}
// 删除最后一个符号
dataStr = dataStr.slice(0,-1)
defaultObj.data = dataStr
}
// 创建一个请求对象
let xhr = createXhr()
// 设置open请求
xhr.open(defaultObj.method.toUpperCase(),defaultObj.url,defaultObj.aync)
// send发送请求
if(defaultObj.method.toUpperCase()=="POST"){
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
xhr.send(defaultObj.data)
}else{
xhr.send()
}
// 4、监听
return new Promise(()=>{
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && /^20\d$/.test(xhr.status)) {
//5.接收响应
let res
if(defaultObj.dataType == "json"){
res = JSON.parse(xhr.responseText)//转化为json对象
}else{
res = xhr.status
}
success(res)
}
//服务器的响应 状态码
if(!/^20\d$/.test(xhr.status)){
error(xhr.status)
}
}
})
}
jsonp promise版本(无回调函数)
function jsonp(object){
// {链接地址,参数(对象),回调函数名字,回调函数}
let {url,params,callbackName} = object
// 给window添加方法
// 随机生成一个函数名 不能重复
return new Promise((success,error)=>{
try {
let fnName = "fn" + Date.now() + Math.ceil(Math.random()*10000)
// 将对应回调函数添加給window 添加的函数名随机
window[fnName] = success
// 创建标签script
let script = document.createElement("script")
// 将方法名拼接到url地址后面 跨域执行xxx
url += `?${callbackName}=${fnName}`
// 将参数拼接
url += joinParams(params)
// 将这个url地址给到script标签的src属性(自带的属性)
script.src = url
// 将script加到body
document.body.appendChild(script)
// 判断是否已经加载成功,加载成功后就删除script节约空间
script.onload = function(){
script.remove()
delete window[fnName]
}
script.onerror = function(){
error("错误")
}
} catch (error) {
error("又错了")
}
})
}
function joinParams(params){
let str = ''
// 取出对象的值
for(let key in params){
str+=`&${key}=${params[key]}`
}
return str
}
测试
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="text" placeholder="停止输入1s后搜索">
<!-- <script src="./JSONP.js"></script> -->
<script src="./promiseJSONP.js"></script>
<script src="./myajax.js"></script>
<script>
let url = "https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su"
let input = document.querySelector('input')
// promiseJSONP.js用return Premise
let antishake1 = antishake(function () {
let inputValue = input.value
let promise1 = jsonp({
url,
params: {
wd: inputValue
},
callbackName: 'cb',
})
promise1.then((res) => {
console.log(res)
})
promise1.catch((err) => {
console.log(err);
})
}, 1000)
input.oninput = function () {
antishake1()
}
// JSONP.js用callback
// jsonp({
// url,
// params:{
// wd:"江月奥"
// },
// callbackName:'cb',
// callback(res){
// console.log(res)
// }
// })
let promise1 = jsonp({
url,
params: {
wd: "江月奥"
},
callbackName: 'cb',
})
promise1.then((res) => {
console.log(res)
})
promise1.catch((err) => {
console.log(err);
})
</script>
</body>
</html>