AJAX:Asynchronous JavaScript and XML

Web函数的调用方式

传统的Web函数调用过程完全由浏览器代理,即发起HTTP调用、接收结果和进行本地处理等过程完全由浏览器包办:

  • 用户在当前页面点击链接或提交按纽,浏览器作为代理,向服务端发起请求,获得返回的html文档,然后渲染为新页面,并替换掉旧页面
    • 从用户角度看,即当前窗口有一个明显地刷新,新页面替代掉了旧页面,地址栏变换为新页面地址

可否允许开发者编写代码来自行发起调用、接收结果和本地处理?

  • 用户点击链接或提交按纽,由程序员的脚本作为代理,向服务端发起请求,获得返回的json数据
  • 将收到的json数据使用DOM API对当前页面进行操纵
    • 从用户角度看,浏览器并不会刷新页面,当前页面只是发生了局部的更新,因此地址栏也不会发生变化。

由用户代码接管Web调用的优劣

  • 单页效果:如用户注册流程中,用户名重复导致报错,无需等待整个页面被提交,改善用户体验
  • 局部更新:如用户名重复的错误信息直接显示在用户名字段旁,无需刷新整个页面
  • 客户端动态页面:可以由客户端生成整个页面,服务端只需提供json数据即可,更为灵活

历史上的尝试:示例说明

下面的Web函数返回一个json数据(可能是静态硬编码或由服务端脚本动态生成),现在如何由程序员编写的脚本进行调用、接收和处理?

// http://x.com/data.json
{"tom":["black",true,1577808000],"cat":["yellow",false,1609430400]}

1577808000, 1609430400 都是Unix时间戳,分别表示 2020-01-01和 2021-01-01

http://x.com/index.html

<script src='./data.json' > // data.json中的内容是数据或字面量(literal),显然并非合法代码,因此js引擎会抛出错误
  var data = JSON.parse(???); // 
</script>

问题:如何将data.json返回的字符串数据,转换为代码?

解决方案一:以代码的方式载入

http://x.com/data.js

var data = {"tom":["black",true,1577808000],"cat":["yellow",false,1609430400]}

http://x.com/index.html

<script src='/data.js'>
  // 由script标记将data.js中的字符串数据转化为js代码
  let object = JSON.parse(data); // 这一段代码有必要吗?
</script>

问题:需要服务端和浏览器端共同约定变量名,并且是一个全局变量

解决方案二:以数据方式载入

http://x.com/index.html

let data = fetch("./data.json"); // 假设有一个fetch函数,它读取远程的data.json文件,并将其内容读取为本地的字符串
let object = JSON.parse(data); // => js 对象

问题:如何实现上述fetch函数?

如果你自己编写一个HTTP客户端或浏览器,譬如在移动端原生应用的开发中,你就可以使用HTTP客户端库发起任何调用请求、任意处理响应的数据

解决方案三:巧用 script 标记

http://x.com/data.js

var data = {"tom":["black",true,1577808000],"cat":["yellow",false,7122634433357]};

http://x.com/index.html

function fecth(url){
    var s = document.createElement('script');
    s.type = 'text/javascript';
    s.async = true; //加载方式为异步
    s.src = url;
    document.getElementsByTagName('body')[0].appendChild(s);
}
fecth('./data.js');
console.log(data.tom)

实际上是方案一的变形,其缺陷仍然是:

  • Web函数返回值是文本类型(合法的javascript源代码),而非json数据
  • 需要借助全局变量,并且变量命名易存在冲突

AJAX: Asynchronous JavaScript and XML

  • AJAX 是由浏览器内生支持的获取服务端的新模式,它允许由程序员编写的js脚本发起请求,接收和处理返回的数据
  • 因为服务端函数属于网络资源,故总是以异步的方式进行工作
    • 即采用回调函数的方式进行工作
  • 程序员通常会采用返回JSON格式数据作为调用的数据格式
    • ajax早期使用xml,但后续改为更为简单易用的json

原生ajax示例 jquery ajax示例

AJAX 示例

http://x.com/data.json

{"tom":["black",true,1577808000],"cat":["yellow",false,7122634433357]};

http://x.com/index.html

  $.get("./data.json",function(data,status){
    let object = JSON.parse(data); 
    object.cat[0] = 'white';    
    // 执行dom更新或其它任意操作
  });

简化起见,使用了jquery提供的ajax库,请自行加上对jquery的引用

异步调用 vs. 同步调用

var data = $.get("./data.json"); //同步调用写法,错误!
let object = JSON.parse(data); 
object.cat[0] = 'white';

上述代码是错误的,因为Ajax天生只支持异步调用方式,这是由于网络请求是不可靠的,可能成功,也可能不成功(如网络中断、信号不好等),如果使用同步的方式,则意味着限入无限等待,从而形成白屏或卡死等糟糕的用户体验

异步调用的写法是,传入一个函数引用,该函数将会在数据成功返回后被执行,请参考定时器的用法

参考

results matching ""

    No results matching ""