JSONP

jsonp

            概述:JSONP是一种跨域解决方案,它主要是利用了script标签不受跨域影响的特性来完成对应的请求操作。实际上是一个get请求。

什么叫跨域

同源策略(属于浏览器的)为了安全性。

            浏览器采用了对应的同源策略,它防止了对应的恶意请求以及其他非正常请求(一定程度)

同源策略对应的要求

            协议相同
            端口号相同
            ip地址相同

跨域的产生(由于同源策略影响 导致后台接口不能被访问)

            协议不同
            端口不同
            ip地址不同
            ftp请求资源不同也跨域    

跨域的解决

        后端解决(设置响应头)

           
            response.setHeader('Access-Control-Allow-Origin','*') //设置所有的请求地址都允许跨域
            response.setHeader('Access-Control-Allow-Origin-Method','*') //设置所有请求方法都允许跨域

 

        前端解决 (JSONP)

        代理服务器

            iframe script link 都不受跨域的影响(src href)
            webSocket(套接字)

        JSONP

        JSONP的优点:

            它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老
            的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持;并且在请求完毕后可以通过调用
            callback的方式回传结果。

        JSONP的缺点:

            它只支持GET请求而不支持POST等其它类型的HTTP请求; jsonp使用的场景--查询居多          

        百度搜索接口

            https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=miqi&cb=fn
 
            wd表示关键词 cb表示回调函数 通过回调函数将对应的结果传出

        JSONP的流程

            
            <script>
                // var wd = '奥特曼'
                function fn(result){
                console.log(result);
                }
            </script>
            <script src="https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=奥特曼&cb=fn"></script>

 

        由上述代码我们可以看到这个fn这个函数 我们根本没有调用 而是通过链接一个script地址来完成对应的
        数据请求及函数调用。所以在这个里面回调函数是服务端调用的。

        JSONP的封装

            
                function jsonp(url,param={},paramName,callback){
                if(typeof url != 'string'){
                    throw new Error('url必须为字符串')
                }
                url += '?'
                // 将param转为&拼接
                for(let key in param){
                    url += `&${key}=${param[key]}`
                }
                //函数名需要加工(保持的函数名的唯一)
                let callbackName = 'fn' + Date.now() + Math.ceil(Math.random()*10)
                //加给对应的window
                window[callbackName] = callback
                //将参数名和回调函数名传入
                url += `&${paramName}=${callbackName}`
                //创建一个script标签
                let script = document.createElement('script')
                //指定对应的src地址
                script.src = url
                //加给body
                document.body.appendChild(script)
                //script标签加载完毕
                script.onload = function(){
                    this.remove() //将script标签删除
                    delete window[callbackName] //将对应的属性删除
                }
            }

 

        promise封装

            
             function jsonp(url,param={},paramName){
                return new Promise((resolve,reject)=>{
                    if(typeof url != 'string'){
                        throw new Error('url必须为字符串')
                    }
                    url += '?'
                    // 将param转为&拼接
                    for(let key in param){
                        url += `&${key}=${param[key]}`
                    }
                    //函数名需要加工(保持的函数名的唯一)
                    let callbackName = 'fn' + Date.now() + Math.ceil(Math.random()*10)
                    //加给对应的window
                    window[callbackName] = resolve //resolve里面的参数会被then接收 这个resolve会被服务器自动调用并传入参数
                    //将参数名和回调函数名传入
                    url += `&${paramName}=${callbackName}`
                    //创建一个script标签
                    let script = document.createElement('script')
                    //指定对应的src地址
                    script.src = url
                    //加给body
                    document.body.appendChild(script)
                    //script标签加载完毕
                    script.onload = function(){
                        this.remove() //将script标签删除
                        delete window[callbackName] //将对应的属性删除
                    }
                    //script报错的时候
                    script.onerror = function(err){
                        reject('错误'+err)
                    }
                })
            }

 

http协议

        缓存

            缓存提高的文件访问速度,减少请求。locaStorage本地缓存 sessionStorage 本地缓存。从
            locaStorage读取 速度比对应的请求速度要快。提高对应的效率。(优化)
 
            在http请求的过程中 如果你重复的请求 ,我们服务器并不会重复的响应(如果是重复响应服务器压力
            就很大了),所以你http内部就存在了缓存机制。

        强制缓存(http请求里面)

            强制缓存不会让你发送请求(直接从缓存读取)状态200

 

 

            cache-control http2.0 缓存控制器 相对时间
               
                 cache-control:max-age=60
                //60秒内 再访问这个网站 从本地读

 

            expires http 1.0 过期时间 绝对时间

        协商缓存 (http请求里面)

            协商缓存一定会请求,文件如果改变了 就会通过协商缓存(验证文件是否变化 变了重新响应过来 没变
            化就先回来再从本地读取)状态码 304(没变)或者200(变了)
            etag 标识根据对应hash码生成一个特定的码,文件一变这个码会重新生成(根据它就可以区分是否变化了)
            last-modified 最后的修改时间 (时间如果改了 证明对应文件就变了 就可以区分文件是否发生变化)

        优先级 强制缓存高于协商缓存

总结

            先强制缓存 再协商缓存
            文件没变强制缓存 文件变了协商缓存
            强制缓存不会请求 协商缓存会请求

Axios

            axios是一个基于promise的http请求库。

特性

            从浏览器中创建 XMLHttpRequests
            从 node.js 创建 http 请求
            支持 Promise API
            拦截请求和响应(拦截器)
            转换请求数据和响应数据 (自动进行数据转换)
            取消请求(可以请求取消)
            自动转换 JSON 数据 (转换的数据形式以json格式体现)
            客户端支持防御 XSRF (安全性高)
            
            <script src="./axios.min.js"></script>
            <script>
                // 拦截器
                //请求拦截
                axios.interceptors.request.use(config => {
                    // Do something before request is sent
                    return config;
                }, error => {
                    // Do something with request error
                    return Promise.reject(error);
                });
                //响应拦截
                axios.interceptors.response.use(response => {
                    // Do something before response is sent
                    return response;
                }, error => {
                    // Do something with response error
                    return Promise.reject(error);
                });
                //指定请求的根路径
                axios.defaults.baseURL= 'https://autumnfish.cn'
                //指定请求头
                // axios.defaults.headers
                //指定超时时间
                // axios.defaults.timeout
                axios.get('/top/playlist', {
                        limit: 10
                    })
                    .then(res => {
                        console.log(res)
                    })
                    .catch(err => {
                        console.error(err);
                    })
                // axios.post(url,params)
                // .then(res => {
                //     console.log(res)
                // })
                // .catch(err => {
                //     console.error(err);
                // })
                // delete
                // put
                // patch
                // all 所有请求都适配
            </script>

 

posted @ 2022-08-23 21:39  一对7  阅读(147)  评论(0编辑  收藏  举报