同源政策jsonp与解决异步的aysnc

同源政策

浏览器的同源政策

出于安全性的考虑 他只允许对应的两者是同源的内容进行交互和访问,不同源的内容不允许访问

跨域

1.访问协议不同 http https
2.域名不同 百度 搜狐
3.端口号不同
4.走的file协议 文件不一样也会跨域

解决跨域方法

1.添加请求头 后端添加请求头 access-control-allow-origin:* 跨域地址
2.前端也可以添加请求头:setRequestHeader
3.jsonp形式 利用link script ifarme 这三个标签不受跨域影响 只能解决get请求方式
jsonp基础案例
<script>
function a(str){
    console.log(str);
    //ajax请求 自己请求自己
}
//给窗口添加一个方法
window["abc"] = a
//相当于这里会自动执行window的abc方法 也就是上面的a方法 将数据填入a方法的形参
<script src="https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?cb=abc&wd=hello"></script>

jsonp封装

function jsonp({
    url,//链接地址
    params,//参数   对象类型
    callbackName,//回调函数名字
    callback,//回调函数
}){
        //1.给window添加方法    方法名不能重复
        // 随机生成一个函数名
        let fnName = 'fn'+Date.now()+Math.ceil(Math.random()*1000)
        window [fnName] = callback   //传递给.then方法的参数是success来传递
        //2.添加script
        let script = document.createElement('script')
        //3.将方法名拼接到url地址后面
        url +=`?${callbackName}=${fnName}`
        //4.将参数再做拼接
        let paramsStr = joinParams(params)
        url +=paramsStr
        //5.将这个url地址给script标签
        script.src = url
        //6.将script加给body
        document.body.appendChild(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
    }
}
使用promise的jsonp封装
function jsonp({
    url,//链接地址
    params,//参数   对象类型
    callbackName,//回调函数名字
}){
    return new Promise((success,error)=>{
        //1.给window添加方法    方法名不能重复
        // 随机生成一个函数名
        let fnName = 'fn'+Date.now()+Math.ceil(Math.random()*1000)
        window [fnName] = success   //传递给.then方法的参数是success来传递
        //2.添加script
        let script = document.createElement('script')
        //3.将方法名拼接到url地址后面
        url +=`?${callbackName}=${fnName}`
        //4.将参数再做拼接
        let paramsStr = joinParams(params)
        url +=paramsStr
        //5.将这个url地址给script标签
        script.src = url
        //6.将script加给body
        document.body.appendChild(script)
        //判断是否已经加载成功
        script.onload = function(){
            script.remove()
            delete window[fnName]
        }
        //如果加载出错
        script.onerror = function(){
            error('加载出问题')
        }
    })
}
function joinParams(params){
    let str =''
    //取出对象里面的值
    for(let key in params){
        str +=`&${key}=${params[key]}`
        return str
    }
}

async与 await

es7新增了async同步 await 等待 俩个修饰来帮我们解决promise代码冗余的问题

async 他是用来修饰函数的 函数执行他返回的也是一个promise对象,里面东西他可以使用await来修饰 这个修饰也是一个promise对象

async函数可能包含0个或者多个await表达式。await表达式会暂停整个async函数的执行进程并出让其控制权,只有当其等待的基于promise的异步操作被兑现或被拒绝之后才会恢复进程。

        (async function name (){
            await fn('张三',3000)   //本来是异步执行,现在是同步执行
            await fn('李四',2000)   //本来是异步执行,现在是同步执行
            console.log('吃饭');
            //所以是三秒后先打印张三点击了,再2秒后打印李四点击,再打印吃饭

        })()
        
        function fn(str,time){
            return new Promise((success,error)=>{
                setTimeout(()=>{
                    console.log(str+'点击了');
                    success()
                },time)
            })
        }
//总结:
// async 是用于修饰函数 返回值是一个promise对象 async替代了promise
// await是async里面一个修饰符 当他修饰一个promise对象的时候 他会获取程序的控制权 直到完成或失败结束
//await替代了promise中的.then 
// await关键字只在async函数内有效

使用promise的jsonp制作的例子(百度输入框)

    <input type="text">
    <ul id="box"></ul>
    <script src="./promise.jsonp.js"></script>
    <script>
        let input = document.querySelector('input')
        let box = document.getElementById('box')
        var url = "https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su"
        input.onkeyup = throttle(function(){
            //如果内容为空删除
            if(input.value.trim()==''){
                box.remove()
                return
            }
            //删除ul及里面内容  在创建一个ul
            box.remove()
            let ul = document.createElement('ul')
            
            ul.id = 'box'
            document.body.appendChild(ul)
            box = document.getElementById('box')
            //在事件里面进行jsonp请求
            let promise = jsonp({
                url,
                params:{
                    wd:input.value
                },
                callbackName:'cb'
                
            })
            promise.then((res)=>{
                //获取数据(判断数据是否为null)
                if(res.s.length !=0){
                    //遍历数据
                    for(let v of res.s){
                        //添加li
                        let li = document.createElement('li')
                        li.innerText = v
                        box.appendChild(li)
                        //使用事件委托机制,加给父类box
                        //移进事件
                        box.onmouseover = function(e){
                            if(e.target.nodeName=='LI'){//判断是否为li,为box不执行
                                for(let li of box.children){
                                li.style.background = ''
                                }
                                e = e||window.event
                                e.target.style.background = 'skyblue'
                            }
                                
                                
                        }
                        //点击事件
                        box.onclick = function(e){
                            e = e||window.event
                            input.value  = e.target.innerText
                        }
                    }
                }
            })
        },200)
        //节流
        function throttle(fu,wait){//传入参数  执行的函数,等待时间
            let time = null//节流阀
            
            return function(){
                if(time){   //null就是false,执行下面的,true直接跳过
                return
                }
                time = setTimeout(()=>{
                    fu()
                    time = null//做完后节流阀设置为null
                },wait)
            }
        }
    </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值