版权声明:原创文章,未经授权,请勿转载
这篇文章最初发表于 2016.02.17 ,
现在回看发现写得太粗糙了,
各种大小写混淆、排版问题惨不忍睹,
所以大刀阔斧重新修改完善一下。
当时解决的主要问题是如何通过 Ajax 传递数据到服务器,
现在补充完善一些其他的基础知识。
修改于 2016.06.25
若有不对的地方,请多多指教。
下面这段废话是开篇的原始版本,可直接忽略:
The code's source is a lesson named PHP&AJAX from tutorialspoint,
I typed them while learn how to pass information to the server in my Web page. I wrote the comments in the learning process, which perhaps be helpful for beginners to learn new concepts such as XMLHttpResquest.
AJAX
首先要知道的是 AJAX 的全称是 Asynchronous JavaScript and XML。
简单说说异步传输(Asynchronous)是什么,早期的页面内容更新需要完全重新加载(reload),而异步传输解决的就是,在不重新加载的情况下更新页面的内容。
对于用户最直观的感觉是,页面在没有「闪一下」的情况下也能出现新内容。举个栗子,刷电商网站页面时,最初不会把所有内容都加载出来,(那样需要你有极大的耐心),而利用异步传输则可以实现让加载跟随着你浏览的脚步进行,而且让你可以边浏览边加载。
XMLHttpRequest
为什么要提到 XMLHttpResquest?
XML HTTP Request(简称 XHR)是 AJAX 实现异步传输所使用的工具,XMLHttpRequest
最初由微软开发 Outlook 时提出。
作为一个 JavaScript 对象,XMLHttpRequest
可以取回一个 URL 上所有类型的的资源数据,数据类型并不局限于 XML, 还支持 HTTP、File 和 FTP 协议。
引用一段《JavaScript DOM 编程艺术》中的解释,关于 XMLHttpRequest 对象发挥的作用:
Ajax 技术的核心就是 XMLHttpRequest 对象。这个对象充当着浏览器中的脚本(客户端)与服务器之间的中间人的角色。以往的请求都由浏览器发出,而 JavaScript 通过这个对象可以自己发送请求,同时也自己处理响应。
我的理解,也就是说以前 JavaScript 需要通过浏览器的帮助来处理 Request/Response ,而 AJAX 的出现对于 JavaScript 就像段誉的神仙姊姊,让他通过北冥神功(XMLHttpRequest),不需要通过年复一年的练功(曾经的浏览器)而获得内力(Request/Response),可以直接自己吸取内力(不需借助浏览器而自己处理)。
这个比喻有点牵强,但是整体的作用是一样的,让 JavaScript 自己有了新力量。
XMLHttpRequest 的相关属性
onreadystatechange
——JavaScript 函数对象,指定在 readyState
的状态码改变时,所调用的函数。用于指定 JavaScript 用哪个函数来处理服务器返回的响应。
readyState
——Http 请求的状态值,取值 0~4 代表不同的状态,0 表示请求未初始化,3 表示在交互之中,4 表示 DONE 请求完成。
对应的 5 个状态的英文是: uninitialized, loading, loaded, interactive, complete.
代码应用
了解了 XMLHttpRequest
的简单属性之后,就可以通过一个简单的完整例子来看一下 AJAX 的修炼办法,MDN 中有个简单实例帮助理解 AJAX 。具体代码可见 Getting_Started-AJAX 里的步骤三。
下面讲讲我的理解。
MDN 的实例中,JavaScript 里用了两个 function
(感觉说方法好容易有歧义),第一个发送请求,第二个处理响应。连接这两个 function
之间的则是 onreadystatechange
。我画一张图来理了一下 JavaScript 的过程细节,也就是从 HTML 页面触发 JS 异步传输后发生的事情:
从编程的角度来看,具体操作细节是这样:
- 实例化一个
XMLHttpRequest
对象,这里涉及到一些小问题
- 对于不同浏览器兼容性的处理,一种是 Mozilla、Safari 使用的
XMLHttpRequest
,一种是 IE 使用的ActiveXObject
。 - 对于一些 Mozilla 浏览器,如果服务器的响应没有 XML mime-type header,可能会无法正常工作,故需要修改
header
。[这里具体的细节还需要去查] -
XMLHttpRequest
对象实例化之后,在正式发送请求之前,需要告诉它,这个请求发送出去后,如果服务器返回了响应该如何处理,所以借用onreadystatechange
,并指定一个函数来处理 。 - 为什么要用
onreadystatechange
?
这里只能算是借用它来帮助我们,它有点像监听,可以时刻探听到发送出去的请求的状态,一旦这个状态发生改变,则进行下一步。但要注意,它仅仅只能是发现「请求状态变了」,而真正判断是否返回了响应,是由另一个函数来进行的。 - 这另一个函数做了什么?
想象一下,这个函数的出场机会很多,每次请求状态发生改变的时候都会调用它。但它真正的使命是处理服务器返回的响应内容。那么如何判断已有了想要的响应?
还记得前面提到的XMLHttpRequest
的属性中的readyState
吗,现在通过第一步判断readyState
是否为 4(已成功),第二步判断响应的状态,也就是普通请求的状态码是否为 200。通过这两关这样筛选,识别出服务器了返回响应,(去掉了其他无关的出场机会,开始正式的大戏)。
所用的两条判断语句(httpRequest 是
XMLHttpRequest
实例的名称)
if (httpRequest.readyState == 4) {
if (httpRequest.status == 200) {
// 处理响应内容
} else {
// 响应有问题
}
}
- 重复一下整体的思路:onreadystatechange 实时监控请求的状态,一旦状态变化,调用函数,此函数判断服务器返回响应时,对响应内容进行处理。
- 以上是在定义这个
XMLHttpRequest
实例,创建实例,并定义实例的如何处理后续。 - 接下来便是正式发送请求。调用
XMLHttpRequest
的两个函数open()
和send()
来发送请求。 - open(请求方式[GET/POST/HEAD], 请求的 URL,是否异步处理[true/false] )
- send(若是POST请求时传递的字符串格式的数据)
- 发送成功之后则需要处理响应,而这在之前的
XMLHttpRequest
实例中已经定义好了函数,那便可以按照编好的方式来处理了。
AJAX 调试方法
在 Stack Overflow 上找到一个回答(看这里 )
How to debug AJAX calls (answered by MonkeyZeus)
- Go to the web page which makes the AJAX call
- In Chrome press F12
- Go to the Network tab
- Activate the AJAX call by submitting the form #reservSearch
- In the Network tab look for a call to /Home/GetRates
Click it - Check the Preview and Response tabs to see the output from your server
- Is it displaying the expected HTML data which your AJAX call is listening for?
最初不明白 AJAX 原理的时候,运行起来会不知所措,想要看到自己的 AJAX 是否已经成功得到响应,或是想找到问题出在哪里,可以在 F12 → 网络 → XHR 查看。除此之外,在控制台的错误提醒里面也可以找到一些线索。
举个坑,我在学习过程中单步跟踪脚本时,还未到指定调用的方法,运行就直接结束。查看错误信息:"NetworkError: 404 Not Found - http://localhost:8080/undefined"
。可知,url 没有顺利传输,回去看 http_request.open('GET', url, true);
处代码,发现了错误。(=.= 我把逗号写成了点)
未完待续
参考的网页
https://developer.mozilla.org/zh-CN/docs/AJAX/Getting_Started