• 异步请求及跨域方案


    前端总结系列

    目录

    
    一、异步请求
        1.1 XHR(XMLHttpRequest)
        1.2 Promise(ES6)
        1.3 Fetch
    
    二、跨域方案
        2.1 JSONP(JavaScript Object Notation with Padding)
        2.2 CORS(Cross-origin resource sharing)
    

    一、异步请求

    此文只进行简单的介绍,完整的用例请见我的Github。Github上的用例,对这三种方法的POST和GET请求都进行了封装。

    Github演示不支持POST请求,所以会有部分报错。完整测试可以放在本机的localhost下。

    
    a.json
    -------------
    {
    "user":"张三",
    "folling":30,
    "foller": 20
    }
    

    1.1 XHR(XMLHttpRequest)

    三行代码实现异步请求

    下面是发送XHR请求之后,返回的成功信息。

    
    <script type="text/javascript">
      var xmlhttp = new XMLHttpRequest()  // 创建异步请求
      xmlhttp.open('GET','a.json')  // 使用GET方法获取hello.txt文件
      xmlhttp.send()  // 发送异步请求
    </script>
    

    读取异步请求返回的数据

    返回的数据存储在xmlhttp.responseText。

    怎么返回了这么多内容?请接着往下看。

    
    <script type="text/javascript">
      var xmlhttp = new XMLHttpRequest()
      // 异步请求状态发生改变时会执行这个函数
      xmlhttp.onreadystatechange = function () {
        // 显示返回的内容
        console.log(xmlhttp.responseText)
      }
      xmlhttp.open('GET','hello.txt')
      xmlhttp.send()
    </script>
    

    异步请求的状态

    现在就好了,我们在使用xmlhttp.responseText之前判断了一下当前ajax的状态。确认完成了,我们才返回值。

    
    <script type="text/javascript">
      var xmlhttp = new XMLHttpRequest()
      xmlhttp.onreadystatechange = function () {
        // status == 200 用来判断当前HTTP请求完成
        if ( xmlhttp.readyState == 4 && xmlhttp.status == 200 ) {
          console.log(xmlhttp.responseText)
        }
      }
      xmlhttp.open('GET','hello.txt')
      xmlhttp.send()
    </script>
    

    异步请求一共有五个状态,用来标识异步请求的不同阶段。

    • 0 UNSENT 代理被创建,但尚未调用 open() 方法
    • 1 OPENED open() 方法已经被调用
    • 2 HEADERS_RECEIVED send() 方法已经被调用,并且头部和状态已经可获得
    • 3 LOADING 下载中; responseText 属性已经包含部分数据
    • 4 DONE 下载操作已完成

    上面返回的五条数据中,一条是XHR请求成功默认返回的。前两条对应的状态1和2,是没有返回内容的,所以为空。后面两条有内容的对应的是3和4。

    因此,我们想要数据完全下载完成了再显示返回内容,只需要用if判断一下当前状态是否是4即可。

    关于HTTP状态码代表的意义,可以看我之前写过的文章

    封装XHR方法

    
    function ajax (method,url,callback) {
      var xmlhttp = new XMLHttpRequest()  // 创建异步请求
      // 异步请求状态发生改变时会执行这个函数
      xmlhttp.onreadystatechange = function () {
        // status == 200 用来判断当前HTTP请求完成
        if ( xmlhttp.readyState == 4 && xmlhttp.status == 200 ) {
          callback(JSON.parse(xmlhttp.responseText))  // 执行回调
        }
      }
      xmlhttp.open(method,url)  // 使用GET方法获取
      xmlhttp.send()  // 发送异步请求
    }
    

    调用XHR方法

    
    ajax('GET','a.json',function (res) {
      console.log(res)  // 显示返回的对象
      ajax('GET','b.json',function (res) {
        console.log(res)
        ajax('GET','c.json',function (res) {
          console.log(res)
        })
      })
    })
    

    1.2 Promise(ES6)

    我们在用Ajax写异步的时候,很容易掉入回调地狱(callback),代码的可读性会大大的下降。Promise可以让代码变得更优雅。

    封装基于Promise的XHR

    
    function ajax ( method,url ) {
      // 返回一个Promise对象
      return new Promise(function (resolve) {
        var xmlhttp = new XMLHttpRequest()  // 创建异步请求
        // 异步请求状态发生改变时会执行这个函数
        xmlhttp.onreadystatechange = function () {
          // status == 200 用来判断当前HTTP请求完成
          if ( xmlhttp.readyState == 4 && xmlhttp.status == 200 ) {
            resolve(JSON.parse(xmlhttp.responseText))  // 标记已完成
          }
        }
        xmlhttp.open(method,url)  // 使用GET方法获取
        xmlhttp.send()  // 发送异步请求 
      })
    }
    

    调用基于Promise的XHR

    
    var aj = ajax('GET','a.json')
    aj.then(function (res) {
      console.log(res)
    })
    

    1.3 fetch

    fetch是对Promise的一个封装,使用非常方便。

    fetch('a.json').then(function (res){
       return res  // 返回Promise
    }).then(function (res) {
       return res.json()  // 返回JSON对象
    }).then(function (json) {
       console.log(json)  // 显示JSON内容
    })
    

    二、跨域方案

    CORS方法更好一些,但是需要对服务器有自主权。JSONP则不需要对服务器有自主权,可以通过script、img等标签可以发送GET请求的特点,通过回调函数执行已有的JS函数。在函数内获取返回值。

    CORS支持所有HTTP请求,JSONP只支持GET请求。

    2.1 JSONP(JavaScript Object Notation with Padding)

    
    用回调跨域
    ------------------------
    <script type="text/javascript" src="http://localhost/async/cors.php?callback=go"></script>
    
    设置好回调函数
    ------------------------
    function go (arr) {
      console.log(arr)  // 显示回调的值 | {a:"1"}
    }
    
    script发送的GET请求时,返回的值是一个函数,遂执行回调函数
    ------------------------
    <?php 
    $go=$_GET['callback'];  // 获取callback的值
    echo $go.'({a:"1"})';  // 输出回调函数
    ?>
    
    

    2.2 CORS(Cross-origin resource sharing)

    PHP配置CORS

    
    <?php 
    header("Access-Control-Allow-Origin:*");  // *号为允许所有域名,推荐修改成需要跨域的域名
    ?>
    

    配置CORS前

    配置CORS后

    总结

    下一篇总结Vue。

  • 相关阅读:
    SQL Sever语言 存储过程及触发器
    计蒜客 挑战难题 移除数组中的重复元素
    projecteuler Sum square difference
    码农谷 求前N项之和
    projecteuler Smallest multiple
    计蒜客 挑战难题 寻找插入位置
    Largest palindrome product
    计蒜客 挑战难题 元素移除
    码农谷 球从M米高度自由下落第N次落地时反弹的高度
    挑战难题 奇怪的国家
  • 原文地址:https://www.cnblogs.com/libin-1/p/6658649.html
Copyright © 2020-2023  润新知