美文网首页
AJAX和Promise及跨域

AJAX和Promise及跨域

作者: 前端小码农呀 | 来源:发表于2020-05-10 19:58 被阅读0次

    回调地狱

    封装ajax的时候,发现:请求成功后的值不能直接返回给调用者,而需要在其内部执行一个回调函数。如果在请求一次后需要再次请求,那么,也就是在回调函数中需要再次调用ajax,再次传入回调函数,次数多了以后就形成了回调地狱。难以使用及维护

    回调地狱
    解决:es6中的构造函数Promise解决这个问题。

    基本语法:

    new Promise(function (resolve, reject) {
                          // resolve 表示成功的回调
                          // reject 表示失败的回调
                    }).then(function (res) {
                          // 成功的函数
                    }).catch(function (err) {
                          // 失败的函数
                    })
    

    在promise中,提供了两个参数,分别表示执行成功和失败的回调函数,执行成功调用resolve,失败调用reject即可,具体resolve和reject的执行,分别在then和catch中。这样可以将回调函数变成链式结构,从而解决了回调地狱的问题。
    案例:

    new Promise(function (resolve, reject) {
            ajax({
                url: '第一个请求',
                success(res) {
                    resolve(res)
                }
            })
        }).then(function (res) {
            // 准备发送第二个请求
            return new Promise(function (resolve, reject) {
                ajax({
                    url: '第二个请求',
                    data: { a: res.a, b: res.b },
                    success(res) {
                        resolve(res)
                    }
                })
            })
        }).then(function (res) {
            ajax({
                url: '第三个请求',
                data: { a: res.a, b: res.b },
                success(res) {
                    console.log(res)
                }
            })
        }).catch(function (res) {
        })
    

    then和catch不会同时触发,也就是说,只要一个then出错了,执行最底下的catch就行,所以也就可以连续写多个then,一个catch就行

    终极解决方案:es7提供的async/await

    可以将异步代码写的和同步代码一样
    语法:

      asyncfunctionfn() {
                        constres=awaitpromise对象
                    }
    

    只要是一个 promiser 对象,那么我们就可以使用 async/await 来书写
    案例

    async function fn() {
            const res = new Promise(function (resolve, reject) {
                ajax({
                    url: '第一个地址',
                    success(res) {
                        resolve(res)
                    }
                })
            })
            // res 就可以得到请求的结果
            const res2 = new Promise(function (resolve, reject) {
                ajax({
                    url: '第二个地址',
                    data: { a: res.a, b: res.b },
                    success(res) {
                        resolve(res)
                    }
                })
            })
            const res3 = new Promise(function (resolve, reject) {
                ajax({
                    url: '第三个地址',
                    data: { a: res2.a, b: res2.b },
                    success(res) {
                        resolve(res)
                    }
                })
            })
            // res3 就是我们要的结果
            console.log(res3)
        }
    

    跨域

    原因是浏览器的同源策略
    跨域:前端是不能跨域的,但是后端的语言可以。
    概念:浏览器有同源策略,禁止ajax从一个域名请求另外一个域名上的数据,如果从一个域名请求另外一个域名上的数据,就是跨域

    那什么是同源策略,所谓同源,就是指域名、协议、端口都相同。比如说:一个浏览器打开百度的网站,然后在控制台请求腾讯的网页,浏览器会报一个不是同源的异常。
    解决:

    • 1.php解决跨域:
      也就是说跨域请求只是限制客户端向服务端,如果是服务端向服务端请求的话就不存在这个问题,也就是说需要跨域的请求交给php服务端来做,有了结果再响应给ajax即可。
      原理上利用的php的爬虫技术。有file_get_contents()、curl、ob_get_contents()
      在服务端设置响应头,允许跨域请求
      如果请求的服务端是自己可操作的话,可以在php端设置允许跨域的响应头。代码如下:header("Access-Control-Allow-Origin:*");
    • 2.配置nginx代理:
    location = 自定义url {
    proxy_pass 待跨域请求的地址
    }
    
    • 3.通过jsonp来实现:
      利用标签可以跨域(当前网页的图片链接可以是别的网站上的图片)的特性,制作标签进行跨域
    var script = document.createElement('script');
        script.setAttribute('src', "http://www.php.com/test.php?callback=response");
        $('head').append(script);
        function response(res) {
            $('#result').text(res);
        }
        // php代码:
        $fun = $_GET['callback'];
        echo "$fun(".$str.")";
    

    相关文章

      网友评论

          本文标题:AJAX和Promise及跨域

          本文链接:https://www.haomeiwen.com/subject/pocaihtx.html