XHR 处理不同类型的响应数据, jquery 中的 ajax

415 阅读2分钟

1. XHR 处理 text/plain 类型的响应数据

  • 服务器端:

    • 第一行: 指定发送数据主体类型为纯文本( text/plain ), 不指定默认为 text/html
    header('Content-Type: text/plain; charset=UTF-8');
    echo 'succ'
    
  • 客户端: if (XHR.responseText === 'succ') { ...... }

2. XHR 处理 text/html 类型的响应数据

注意: AJAX 应用中服务器返回的不是完整的 HTML 文档, 而只是 HTML 标签组成的片段

  • 服务器端:

    header('Content-Type: text/html; charset=UTF-8');
    echo '<li>xx</li><li>yy</li>'
    
  • 客户端:

    • ul.innerHTML = XHR.responseText

3. XHR 处理 application/javascript 类型的响应数据

  • 提示: 一般 JS 文件中, script 请求(任何人)(任何时间) JS 内容一样

  • 场景: 需要服务器端返回**动态 JS **, 根据客户端不同或访问时间不同, JS 不同

  • 服务器端

    header('Content-Type: application/javascript; charset=UTF-8');
    echo "var msg = '你好'; alert(msg);"
    
  • 客户端 eval(XHR.responseText)

  • Ex: 实现国际化 欢迎消息

    • 服务器端

      <?php
        // 修改响应头格式
        header('Content-Type: application/javascript; charset=UTF-8');
      	// 读取请求消息所有头部
      	$list = getallheaders();
      	// 读取浏览器首选语言
      	$lang = $list['Accept-Language'];
      	$start = substr($lang, 0, 2);
      	// 根据客户端的首选语言不同, 返回不同格式的欢迎消息
      	if ($start == 'zh') {
          echo "var msg = '你好'; alert(msg);"
        } else if ($start == 'en') {
          echo "var msg = 'hello'; alert(msg);"
        } else {
          echo "var msg = 'hello'; alert(msg);"
        }
      ?>
      
    • 客户端

      window.onload = function () {
        var XHR = new XMLHttpRequest()
        XHR.onreadystatechange = function () {
          if (XHR.readyState == 4 && XHR.status == 200) {
            eval(XHR.responseText)
          }
        }
        XHR.open('GET', 'i18n.php', true)
        XHR.send(null)
      }
      

4. XHR 处理 application/xml 类型的响应数据

4.1. XML 语法

Extensible Markup Language, 可扩展的标签语言, 本身是一种字符串格式, 用于描述批量复合数据

  • XML 文档类型声明
    • <?xml version='1.0' encoding='utf-8' ?>
  • 整个 XML 字符串只有一个根元素
  • 所有的数据放在标签中
    • <标签>数据</标签>
  • 所有标签名都可以自定义, 但严格区分大小写, 且开始标记和结束标记必须完全一样
  • 每个标签都可以定义任意的子标签, 标签可以嵌套, 但不能交叉
    • Ex: <book><id><i>数据</i></id></book>
  • 每个标签都可以自定义属性, 属性必须有值, 值必须用单引号 '' / 双引号 "" 包裹
4.2. HTML 和 XML 的区别
HTMLXML
语法语法随意语法严格
标签标签预定义好了标签都是自定义
作用用于描述网页的结构用于描述数据
4.3. XHR 处理 XML 类型的响应数据
  • 服务器端

    header('Content-Type: application/xml; charset=UTF-8');
    echo '<?xml ?><cakeList><cake><id>1</id><price>100</price></cake><cake><id a='1'></id><price>200</price><cake></cakeList>'
    
  • 客户端

    var doc = XHR.responseXML
    var cakes = doc.querySelectorAll('cake')
    var id = cake.querySelector('id')
    var idTxt = id.innnerHTML
    var attrTxt = id.getAttribute('a')
    

5. XHR 处理 application/json 类型的响应数据

  • 服务器端

    header('Content-Type: application/json; charset=UTF-8');
    $arr = ......;
    $str = json_encode($arr);
    echo $str
    
  • 客户端

    • JSON.parse(XHR.responseText)

6. jquery 中的 ajax

6.1. jquery 中对 ajax 操作封装的函数 -- load()
  • 作用: 用来动态加载一个页面的内容到指定的 DOM 元素上
  • 语法:
    • $('selector').load(URL, [data], [function (response, status, XHR) {}])
      • URL: 请求地址
      • data: 可选, 发送到服务器端的数据
      • function (response, status, XHR) {}: 可选, load 加载完成时运行的回调函数
        • response: 请求的结果数据
        • status: 请求的结果状态( success / notmodified / error / timeout / parsererror )
        • XHR: XMLHttpRequest 对象
  • $(selector).load('xxx.php')
    • 发起一个 XHR 请求, datanullGET 请求, 否则发起 POST 请求; 把服务器端返回的响应数据( 必须是 html 片段 ), 追加为选定元素的 innerHTML
    • 使用限制:
      • 服务器必须返回 html 片段
      • 选定元素的内容必然被清除
  • 使用场景:
    • 当内容是固定不变的, 可以直接加载 HTML 页面
      • $('#header').load('header.html'), $('#foot').load('footer.html')
6.2. jquery 中对 ajax 操作封装的函数 -- get()
  • 使用 HTTP GET 请求从服务器加载数据

  • 语法:

    • $.get(URL, [data], [function (response, status, XHR) { ...... }], [dataType])
      • dataType: 可选, 规定预期的服务器响应的数据类型, jquery 会只能判断类型
        • 可取值: XML / HTML / text / script / json / jsonp
6.3. jquery 中对 ajax 操作封装的函数 -- post()
  • 使用 HTTP POST 请求从服务器加载数据

  • 语法:

    • $.post(URL, [data], [function (response, status, XHR) {}], [dataType])
6.4. jquery 中对 ajax 操作封装的函数 -- ajax()
  • 使用 HTTP 请求从服务器加载数据

  • 语法:

    $.ajax({
      type: 'POST', // 请求方式: POST / GET / PUT / DELETE
      url: 'xxx.php', // 请求地址
      data: { key: value }, // 可选, 请求参数
      beforeSend: function (XHR) {}, // 发送请求前运行的函数
      cache: true, // 浏览器是否缓存响应数据
      async: true, // 是否异步请求
      success: function (response, status, XHR) { ...... }, // 响应完成且请求成功后的回调函数
      error: function (err) { ...... }, // 请求失败后的回调函数
      complete: function (XHR, status) {} // 请求完成后的回调函数, 在请求成功或请求失败后都要调用, 即在 success / error 函数之后调用
    })
    

7. onkeydown, onkeyup, onkeypress 的区别

  • onkeydown 事件最先执行, 其次是 onkeypress, 最后是 onkeyup

  • onkeydown 事件 和 onkeypress 事件 会影响 onkeyup 事件的执行

    • 三个事件同时存在, 都是 alert 的话, 只会弹出 2 个弹窗, onkeyup 事件中的弹窗不会弹出
  • 三者在事件响应上: onkeydown 事件, onkeypress 事件响应的时候, 输入的字符串并没有被系统接收, 而 onkeyup 事件响应的时候, 输入流已经被系统接收;

    • 由于 onkeydown 事件比 onkeypress 事件先执行, onkeydown 触发的时候输入流正要进入系统, 也就是说 onkeydown 事件一完, 输入流就进入了系统, 无法改变, 所以通过 onkeydown 事件可以知道用户是按了哪个键

    • onkeypress 事件则是在输入流进入系统后触发的, 但输入流暂未被系统处理, 此时已经不能改变输入流了

    • onkeyup 事件则是输入流被系统处理后发生的

    • 注意: 在所有浏览器中, onkeypress 事件只能监听字母和数字, 不能监听一些特殊的按键( alt / ctrl / shift / 箭头等 ), 监听用户是否按下按键请使用 onkeydown 事件, 所有浏览器都支持 onkeydown 事件