第17章 Ajax 与 JSON (一)
来源:互联网 发布:it男卖肉夹馍 编辑:程序博客网 时间:2024/05/04 04:36
2005年,Jesse James Garrett 发表了一篇在线文章,题为 "Ajax: A new Approach to Web Applications"。他在这篇文章里介绍了一种技术,用他的话说,就叫Ajax, 是对 Asynchronous JavaScript + XML 的简写。这一技术能够向服务器请求额外的数据而无须卸载页面,会带来更好的用户体验。Garrett 还解释了怎样使用这一技术改变自从 Web 诞生以来就一直沿用的 "单击,等待" 的交互模式。
Ajax 技术的核心是 XMLHttpRequest 对象 (简称 XHR) ,这是由微软首先引入的一个特性,其他浏览器提供商后来都提供了相同的实现。在 XHR 出现之前,Ajax式的通信必须借助一些 hack 手段来实现,大多数是使用隐藏的框架或内嵌框架。XHR 为向服务器发送请求和解析服务器响应提供了流畅的接口。能够以异步方式从服务器取得更多信息,意味着用户单击后,可以不必刷新页面也能取得新数据。也就是说,可以使用 XHR 对象取得新数据,然后再通过 DOM 将新数据插入到页面中。另外,虽然名字中包含 XML 的成分,但 Ajax 通信与数据格式无关;这种技术就是无须刷新页面即可从服务器取得数据,但不一定是 XML 数据。
实际上,Garrett 提到的这种技术已经存在很长时间了。在 Garrett 撰写那篇文章之前,人们通常将这种技术叫做远程脚本 (remote scripting),而且早在 1998 年就有人采用不同的手段实现了这种浏览器与服务器的通信。再往前推,JavaScript 需要通过 Java applet 或 Flash 电影等中间层向服务器发送请求。而 XHR 则将浏览器原生的通信能力提供给了开发人员,简化了实现同样操作的任务。
在重命名为 Ajax 之后,大约是 2005年底 2006年初,这种浏览器与服务器的通信技术可谓红极一时。人们对 JavaScript 和 Web 的全新认识,催生了很多使用原有特性的新技术和新模式。就目前来说,熟练使用 XHR 对象已经成为所有 Web 开发人员必须掌握的一种技能。
17.1 XHR 对象
var xmlHttp;
function createXMLHttpRequest(){
if (window.ActiveXObject) {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} else if (window.XMLHttpRequest){
xmlHttp = new XMLHttpRequest();
}
}
IE5 是第一款引入 XHR 对象的浏览器。在 IE5 中,XHR 对象是通过 MSXML 库中的一个 ActiveX 对象实现的。因此,在 IE 中可能会遇到 3 种不同版本的 XHR 对象,即:MSXML2.XMLHttp、MSXML2.XMLHttp.3.0 和 MSXML2.XMLHttp.6.0 。
IE7、Firefox、Opera、Chrome 和 Safari 都支持原生的 XHR 对象,在这些浏览器中创建 XHR 对象要像下面这样使用 XMLHttpRequest 构造函数:
var xhr = new XMLHttpRequest();
假如你只想支持 IE7 及更高版本,那么可以只用原生的 XHR 实现。
17.1.1 XHR 的用法
在使用 XHR 对象时,要调用的第一个方法是 open(),它接受3个参数:要发送的请求的类型 ("get"、"post" 等) 、请求的 URL 和表示是否异步发送请求的布尔值。下面就是调用这个方法的例子:
xhr.open("get", "example.php", false);
这行代码会启动一个针对 example.php 的 GET 请求。有关这行代码,需要说明两点:一是 URL 相对于执行代码的当前页面 (当然也可以使用绝对路径);二是调用 open() 方法并不会真正发送请求,而只是启动一个请求以备发送。
只能向同一个域中使用相同端口和协议的 URL 发送请求。如果 URL 与启动请求的页面有任何差别,都会引发安全错误。
要发送特定的请求,必须像下面这样调用 send() 方法:
xhr.open("get", "example.php", false);
xhr.send(null);
这里的 send() 方法接受一个参数,即要作为请求主体发送的数据。如果不需要通过请求主体发送数据,则必须传入 null,因为这个参数对有些浏览器来说是必需的。调用 send() 之后,请求就会被分派到服务器。
由于这次请求是同步的,JavaScript 代码会等到服务器响应之后再继续执行。在收到响应后,响应的数据会自动填充 XHR 对象的属性,相关属性简介如下。
- responseText: 作为响应主体被返回的文本。
- responseXML: 如果响应的内容类型是 "text/xml" 或 "application/xml" ,这个属性中将保存包含着响应数据的 XML DOM 文档。
- status: 响应的 HTTP 状态。
- statusText: HTTP 状态的说明。
- 0:未初始化。尚未调用 open() 方法。
- 1:启动。已经调用 open() 方法,但尚未调用 send() 方法。
- 2: 发送。已经调用 send() 方法,但尚未接收到响应。
- 3: 接收。已经接收到部分响应数据。
- 4: 完成。已经接收到全部响应数据,而且已经可以在客户端使用了。
17.1.2 HTTP 头部信息
- Accept: 浏览器能够处理的内容类型。
- Accept-Charset: 浏览器能够显示的字符集。
- Accept-Encoding: 浏览器能够处理的压缩编码。
- Accept-Language: 浏览器当前设置的语音。
- Connection: 浏览器与服务器之间连接的类型。
- Cookie: 当前页面设置的任何 Cookie。
- Host: 发出请求的页面所在的域。
- Referer: 发出请求的页面的 URI。注意,HTTP 规范将这个头部字段拼写错了,而为保证与规范一致,也只能将错就错了 (这个英文单词的正确拼法应该是 referrer)。
- User-Agent: 浏览器的用户代理字符串。
var xhr = createXHR();xhr.onreadystatechange = function(){if(xhr.readyState == 4){if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){alert(xhr.responseText);}else {alert("Request was unsuccessful: " + xhr.status);}}};xhr.open("get", "example.txt", true);xhr.setRequestHeader("MyHeader", "MyValue");xhr.send(null);
17.1.3 GET请求
17.1.4 POST 请求
function submitData(){var xhr = createXHR();xhr.onreadystatechange = function(event){if(xhr.readystatechange == 4){if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){alert(xhr.responseText);}else {alert("Request was unsuccessful: " + xhr.status);}}};xhr.open("post", "postexample.php", true);xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");var form = document.getElementById("user-info");xhr.send(serialize(form));}
这个函数可以将 ID 为 "user-info" 的表单中的数据序列化之后发送给服务器。与 GET 请求相比,POST 请求消耗的资源会更多一些。从性能角度来看,以发送相同的数据计,GET请求的速度最多可达到 POST 请求的两倍。17.1.6 安全
首先,可以通过 XHR 访问的任何 URL 也可以通过浏览器或服务器来访问。下面的 URL 就是一个例子:/getuserinfo.php?id=23如果是向这个 URL 发送请求,可以想象结果会返回 ID 为 23 的用户的某些数据。谁也无法保证别人不会将这个 URL 的用户 ID 修改为 24、56或其他值。因此,getuserinfo.php文件必须知道请求者是否真的有权限访问要请求的数据;否则,你的服务器就会门户大开,任何人的数据都可能被泄漏出去。对于未被授权系统有权访问的某个资源的情况,我们称之为 CSRF (Cross-Site Request Forgery,跨站点请求伪造)。未被授权系统会伪装自己,让处理请求的服务器认为它是合法的。受到 CSRF 攻击的 Ajax 程序有大有小,攻击行为既有旨在揭示系统漏洞的恶作剧,也有恶意的数据窃取或数据销毁。为确保通过 XHR 访问的 URL 安全,通行的做法就是验证发送请求者是否有权限访问相应的资源。有下列几种方式可供选择。
- 要求以 SSL 连接来访问可以通过 XHR 请求的资源。
- 要求每一次请求都要附带经过相应算法计算得到的验证码。
请注意,下列措施对防范 CSRF 攻击不起作用。
- 要求发送 POST 而不是 GET 请求 -- 很容易改变。
- 检查来源 URL 以确定是否可信 -- 来源记录很容易伪造。
- 基于 cookie 信息进行验证 -- 同样很容易伪造。
XHR 对象也提供了一些安全机制,虽然表面上看可以保证安全,但实际上却相当不可靠。实际上,前面介绍的 open() 方法还能再接受两个参数:要随请求一起发送的用户名和密码。带有这两个参数的请求可以通过 SSL 发送给服务器上的页面,如下面的例子所示:xhr.open("get", "example.php", true, "username", "password"); // 不要这样做 !!即便可以考虑这种安全机制,但我们建议还是不要这样做。把用户名和密码保存在 JavaScript 代码中本身就是极为不安全的。任何人,只要他会使用 JavaScript 调试器,就可以通过查看相应的变量发现纯文本形式的用户名和密码。
- 第17章 Ajax 与 JSON (一)
- 第17章 Ajax 与 JSON (二)
- 第17章 Ajax 与 JSON (三)
- AJAX与JSON的一些总结(一)
- AJAX,JSON与MVC
- AJAX,JSON与MVC
- ajax与json
- ajax与json
- ajax与json
- json与ajax
- Ajax与Json
- Ajax与Json
- ajax与JSON
- JSON 与 Ajax
- ajax与json
- S2SH+ajax+json-------(一)
- 拥抱JSON ---- 关于JSON与Ajax
- JSON--Java与AJAX(Jquery)
- AspectJ拦截异常
- c++读文件的一些操作
- java面试题——冒泡排序
- delphi 创建半透明的异形窗口
- ListView获取选中和长按菜单对应的item的_id值
- 第17章 Ajax 与 JSON (一)
- Redis中sorted sets的应用
- vim cook
- 20120316过去的一些url
- linux设备驱动--阻塞IO(续)
- 从内存的角度解释内存对齐的原理
- VC获取对话框指针
- CSS中关于clearfix对float的使用
- 第17章 Ajax 与 JSON (二)