ajax连接池和XMLHttpRequest
连接池
我们公司在路由和交换机web界面和后端交互全部采用的是自己封装的ajax组件完成的,组件有点老了,代码风格和其中的某些用法现在看起来都有点不习惯。今天把这个组件的核心部分的ajax连接池记录下来,如果以后有机会,就重新封装一个。
先看看连接池的代码:
var __XmlHttpPool__ ={
m_MaxPoolLength: 10,
m_XmlHttpPool: [],
__requestObject: function () {
var xmlhttp = null;
var pool = this.m_XmlHttpPool;
for (var i = 0; i < pool.length; ++i) {
if (pool[i].readyState == 4 || pool[i].readyState == 0) {
xmlhttp = pool[i];
break;
}
}
if (xmlhttp == null) {
return this.__extendPool();
}
return xmlhttp;
},
__extendPool: function () {
var xmlhttp = null;
xmlhttp = __getXmlhttp(xmlhttp); //创建新的XHR对象。
if ((xmlhttp) && (this.m_XmlHttpPool.length < this.m_MaxPoolLength)) {
this.m_XmlHttpPool.push(xmlhttp);
}
return xmlhttp;
} };
第9行中通过判断XMLHttpRequest对象的readyState值来获取可以使用的XMLHttpRequest对象(0代表open尚未使用,4代表响应完成),15行则是如果连接池中没有可用的XHR对象,则创建一个新的,并将新的XHR对象放入连接池。由于XHR对象在连接时会消耗资源,如果同时进行的ajax请求的太多会导致页面卡顿甚至浏览器出现未响应情况。所以一般不会同时使用太多的ajax请求。
XMLHttpRequst:
XMLHttpRequest的每个实例都表示一个独立的请求/响应对。由于兼容性问题,一般这样创建XHR对象。
try {
xmlhttp = new XMLHttpRequest();
} catch (e) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
在创建XHR对象后,发起HTTP请求的下一步是调用该对象的open()方法去指定请求的方法和URL。请求的方法一般为post和get,但是DELETE,HEAD,OPTIONS,PUT也是规范中允许的。其中HEAD在很多浏览器上已经得到支持。但是我对关于HEAD等这些方法的使用代码见的不多,仅仅在《javascript权威指南第六版》的例18-13中见到使用HEAD来实现ajax的跨域。OPEN的第二个参数UEL是请求的主题。这是相对于文档的URL,这个文档包含调用open()的脚步,如果指定绝对URL,协议,主机和端口通常必须匹配所在文档的对于内容:跨域的请求通常会报错。(但是当服务器明确允许跨域请求时,即在服务器响应时会发送合适的CORS,2级XMLHttpRequest规范会允许它。)
header('Access-Control-Allow-Origin: http://arunranga.com');
在使用XHR发起http请求时还可以设置请求头,例如POST请求需要"Content-Type"头指定请求主题的MIME类型。对于相同的头调用setRequestHeader()多次,新值不会取代之前指定的值,相反,HTTP请求将包含这个头的多个副本或这个头将指定多个值。由于XMLHttpRequest对象会自动处理cookie、连接时间、字符集和编码判断,所有无法改变Content-Length,Date,Referer,User-Agent,Accept-Charset,keep-Alive,User-Agent,Cookie,Host等。可以指定"Authorization"头,但是通常不用这样做,如果请求一个受到密码保护的URL,可以把用户名和密码作为open()的第四个和第五个参数,则XMLHttpRequest将设置合适的头。open的第三个参数是表示处理HTTP响应是同步还是异步。false表示同步,true表示异步。应当尽量避免使用同步,因为客户端javascript是单线程的,当send()方法阻塞时,它通常会导致整个浏览器UI冻结。当然使用Web Worker除外。
在使用XHR发起HTTP请求的最后一步是指定可选的请求主体并使用send向服务器发送它。GET请求绝对没有主体,使用xmlhttp.sent(null)或直接xmlhttp.send()。POST请求通常拥有主体,同时它应该匹配使用setRequestHeader()指定"Content-Type"头。
- status和statusText属性以数字和文本的形式返回HTTP状态码。
- 使用getResponseHeader和getAllResponseHeaders()能查询响应头。XMLHttpRequest会自动处理cookie:它会从getAllResponseHeaders返回的集合中过滤掉cookie。
为了在响应准备就绪是得到通知,必须监听XMLHttpRequest对象上的readstatechange事件。该事件会获得readyState属性
0 : open()尚未调用
1 : open()已调用
2 : 接收到头信息
3 : 接收到响应主体
4 : 响应完成
XMLHttpRequst 2:
XHR2有监控HTTP请求上传的事件。在实现这些特性的浏览器中,XMLHttpRequest对象将有upload属性。upload属性值是一个对象,它定义了addEventListener()方法和整个progress事件集合,
比如onproress和onload。注意,upload对象没有定义onreadystatechange属性,upload仅能触发新的事件类型。对于XHR对象xmlhttp,可以设置xmlhttp.onprogress以监控响应的下载进度,并设置xmlhttp.upload.onprogress以监控请求的上传进度。关于upload的使用,可以看如下代码:
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST",url);
xmlhttp.upload.progress = function(e){
if(e.lengthComputable){
console.log(Math.round(e.loaded/e.total*100) + "% Complete");
}
}
XHR增加了timeout属性,可以设置HTTP请求的时限。
xmlhttp.timeout = 3000;
XMLHttpRequest对象,不仅可以发送文本信息,还可以上传文件。
假定files是一个"选择文件"的表单元素(input[type="file"]),我们将它装入FormData对象。
var formData = new FormData();
for (var i = 0; i < files.length;i++) {
formData.append('files[]', files[i]);
} //... xmlhttp.send(formData);
从服务器取回二进制数据,较新的方法是使用新增的responseType属性。
如果服务器返回文本数据,这个属性的值是"TEXT",这是默认值。较新的浏览器还支持其他值,也就是说,可以接收其他格式的数据。
你可以把responseType设为blob,表示服务器传回的是二进制对象。
var xmlhttp = new XMLHttpRequest(); xmlhttp.open('GET', '/path/to/image.png'); xmlhttp.responseType = 'blob';
接收数据的时候,用浏览器自带的Blob对象即可。
var blob = new Blob([xhr.response], {type: 'image/png'});
参考资料:
《javascript权威指南》
ajax连接池和XMLHttpRequest的更多相关文章
- ajax连接服务器框架
ajax.js function ajax(url, fnSucc, fnFaild) { //1.创建Ajax对象 if(window.XMLHttpRequest) { var oAjax=new ...
- Swoole Redis 连接池的实现
概述 这是关于 Swoole 入门学习的第九篇文章:Swoole Redis 连接池的实现. 第八篇:Swoole MySQL 连接池的实现 第七篇:Swoole RPC 的实现 第六篇:Swoole ...
- 连接SQLServer时,因启用连接池导致孤立事务的原因分析和解决办法
本文出处:http://www.cnblogs.com/wy123/p/6110349.html 之前遇到过这么一种情况: 连接数据库的部分Session会出现不定时的阻塞,这种阻塞时长时短,有时候持 ...
- C3p0连接池配置
在Java开发中,使用JDBC操作数据库的四个步骤如下: ①加载数据库驱动程序(Class.forName("数据库驱动类");) ②连接数据库(Connection co ...
- Java第三方数据库连接池库-DBCP-C3P0-Tomcat内置连接池
连接池原理 数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”.预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去.我们可以通过设定连接池 ...
- common-pool2 学习:thrift连接池的另一种实现
对象池是一种很实用的技术,经典的例子就是数据库连接池.去年曾经从零开始写过一个thrift客户端连接池.如果不想重造轮子,可以直接在apache开源项目commons-pool的基础上开发. 步骤: ...
- druid连接池获取不到连接的一种情况
数据源一开始配置: jdbc.initialSize=1jdbc.minIdle=1jdbc.maxActive=5 程序运行一段时间后,执行查询抛如下异常: exception=org.mybati ...
- C3P0连接池配置和实现详解
一.配置 <c3p0-config> <default-config> <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数.Default: 3 --> ...
- hibernate+mysql的连接池配置
1:连接池的必知概念 首先,我们还是老套的讲讲连接池的基本概念,概念理解清楚了,我们也知道后面是怎么回事了. 以前我们程序连接数据库的时候,每一次连接数据库都要一个连接,用完后再释放.如果频繁的 ...
随机推荐
- 窗口截图(可指定HWND窗口句柄)(三篇文章)
BOOL SaveHwndToBmpFile(HWND hWnd, LPCTSTR lpszPath) { HWND hDesktop = ::GetDesktopWindow(); ASSERT(h ...
- c++继承中的内存布局
今天在网上看到了一篇写得非常好的文章,是有关c++类继承内存布局的.看了之后获益良多,现在转在我自己的博客里面,作为以后复习之用. ——谈VC++对象模型(美)简.格雷程化 译 译者前言 一个C ...
- 使用原生JavaScript
如果你只需要针对现代浏览器,很多功能使用原生的 JavaScript 就可以实现. DOM Selectors //jQuery var ele = $("#id .class") ...
- 298. Binary Tree Longest Consecutive Sequence
题目: Given a binary tree, find the length of the longest consecutive sequence path. The path refers t ...
- Ubuntu Server搭建svn服务以及迁移方法【转】
转自:http://www.linuxidc.com/Linux/2013-05/84693.htm Ubuntu Server搭建svn服务以及迁移方法 采用apache+svn,http访问方式. ...
- 通过外网IP访问内网
外网服务器:外网IP1,内网IP192.168.2.156 内网服务器:内网IP192.168.2.206 通过访问外网服务器8083端口,转发到内网服务器的8083端口. 在外网服务器设置映射规则: ...
- hibernate annotation配置经验
1.将annotation写在entity类文件的get方法上面
- @jsonignore的作用
作用是json序列化时将java bean中的一些属性忽略掉,序列化和反序列化都受影响. 如下: package com.hzboy.orm; import java.util.List; impor ...
- how bootstrap fit into our website design?
在web相关技术中,HTML代表了content,structure, CSS则负责styling,决定内容是如何展示的,javascript则主要负责interactive, behaviour. ...
- Qt之等待提示框(QMovie)
简述 关于gif的使用在实际项目中我用的并不多,因为我感觉瑕疵挺多的,很多时候锯齿比较严重,当然与图存在很大的关系. 关于生成gif的方法可以提供一个网站preloaders,基本是可以满足需求的. ...