day23JSONP讲解

同源策略(浏览器的一种机制)

概述:

浏览器为了安全,它产生的一种同源策略,这个策略是为了防止一些恶意的请求,保护对应的隐私。

同源策略主要是对应的三个内容 分别为

  • 同协议(http/https)

  • 同ip地址(127.0.0.1本机)

  • 同端口号(80 HTTP 的 443 HTTPS 的)

如果不同就会产生一个问题就是跨域问题

import {ajax} from './ajax_promise.js'
//请求一个地址 //sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=miqi&cb=fn
ajax('https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=miqi&cb=fn',{}).then(res=>{
    console.log(res);
})

跨域问题的产生(以下任意一点不同就会跨域)

  • 协议不一样

  • 端口不一样

  • ip地址不一样以文件访问(不同的文件资源也会跨域)

跨域问题的解决

  • 1.前端解决 (JSONP)(需要后端给的是JSONP的接口)

  • 2.后端解决 (在对应的响应头进行设置)

respones.setHeader('Access-Control-Allow-Origin','*')//所有的地址都可以访问我
respones.setHeader('Access-Control-Allow-Origin-Method','*')//所有的请求都可以访问我

3.使用服务器代理(proxy)

4.使用websocket(走的不是http协议)

JSONP

概述:

他是通过script标签不受跨域的影响的特性来解决跨域问题的。(核心就是对应的请求不是我去请求而 是服务器自己请求自己将数据通过回调函数传给我),他的核心还是一个get请求。

简单的JSONP

<!-- wd表示关键词 cb表示回调函数 -->
    <script>
    //他会自动执行你传入的回调函数并且将结果传递给这个函数
    //res里面就会执行完的数据
    function callback(res){
    console.log(res);
}
</script>
<script src="https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?
wd=miqi&cb=callback"></script>

jsonp封装

//请求地址 参数 回调函数 回调函数
export const jsonp=(url,param,callbackName,callback)=>{
    //提取param参数加入到url中
    for(let key in param){
        if(url.includes('?')){
            url += `&${key}=${param[key]}`
        }else{
            url += `?${key}=${param[key]}`
        }
    }
    //将回调函数加给window
    //随机生成一个名字
    let fnName = 'fn'+Date.now()+Math.ceil(Math.random()*30)
    window[fnName] = callback
    //将回调的函数及相关名字拼接到url
    url += `&${callbackName}=${fnName}`
    console.log(url);
    //创建一个script标签
    let script = document.createElement('script')
    //给这个script标签设置src地址
    script.src = url
    document.body.appendChild(script)
    //(必须等待script标签加入到页面才会触发)
    script.onload = ()=>{
        // 将script标签加入到对应的页面
        // 将window的函数删了
        delete window[fnName]
        //再将script标签删除
        script.remove()
    }
}

案例:百度搜索

<input type="text" />
    <ul></ul>
<script type="module">
    // 导入jsonp
    import {jsonp} from './JSONP.js'
//https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=miqi&cb=fn
document.querySelector('input').oninput = function(){
    jsonp('https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su',{
        wd:this.value
    },"cb",(res)=>{
        document.querySelector('ul').innerHTML = ""
        res.s.forEach(v=>{
            document.querySelector('ul').innerHTML += `
<li>${v}</li>
`
        })
    })
}
</script>

JSONP的promise封装

//请求地址 参数 回调函数 回调函数
export const jsonp=(url,param,callbackName)=>{
    return new Promise((resolve,reject)=>{
        //提取param参数加入到url中
        for(let key in param){
            if(url.includes('?')){
                url += `&${key}=${param[key]}`
            }else{
                url += `?${key}=${param[key]}`
            }
        }
        //将回调函数加给window
        //随机生成一个名字
        let fnName = 'fn'+Date.now()+Math.ceil(Math.random()*30)
        window[fnName] = resolve
        //将回调的函数及相关名字拼接到url
        url += `&${callbackName}=${fnName}`
        console.log(url);
        //创建一个script标签
        let script = document.createElement('script')
        //给这个script标签设置src地址
        script.src = url
        document.body.appendChild(script)
        //(必须等待script标签加入到页面才会触发)
        script.onload = ()=>{
            // 将script标签加入到对应的页面
            // 将window的函数删了
            delete window[fnName]
            //再将script标签删除
            script.remove()
        }
        script.onerror =()=>{
            reject()
        }
    })
}

测试

<!DOCTYPE html>
    <html lang="en">
        <head>
        <meta charset="UTF-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
                <meta name=
                    "
viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
    ul{
        list-style: none;
    }
</style>
</head>
<body>
    <input type="text" />
        <ul>
        </ul>
<script type="module">
    // 导入jsonp
    import {jsonp} from './JSONP_promise.js'
//https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=miqi&cb=fn
document.querySelector('input').oninput = function(){
    jsonp('https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su',{
        wd:this.value
    },"cb").then((res)=>{
        document.querySelector('ul').innerHTML = ""
        res.s.forEach(v=>{
            document.querySelector('ul').innerHTML += `
<li>${v}</li>
`
        })
    })
}
</script>
</body>
</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值