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:连接池的必知概念 首先,我们还是老套的讲讲连接池的基本概念,概念理解清楚了,我们也知道后面是怎么回事了. 以前我们程序连接数据库的时候,每一次连接数据库都要一个连接,用完后再释放.如果频繁的 ...
随机推荐
- 在db2中 两个数据库之间的两个表的联合查询
大家好,今天遇到了在db2中 两个数据库之间的两个表的联合查询 我知道oracle中有dblink,可是不知到db2的两个数据库联合查询怎么处理我找了类似于比如两个数据库: db1,db2用户名密码s ...
- ThreadLocal实现session中用户信息 的线程间共享(精)
ThreadLocal并不难理解,我总结的最简单的理解就是: ThreadLocal像其它变量一样(局部.全局.静态)也是一种变量类型,只是他是线程变量,更直白的说他是一种变量作用域,即他的作用域是当 ...
- java string,需要进行首字母大写改写
java string,需要进行首字母大写改写,网上大家的思路基本一致,就是将首字母截取,转化成大写然后再串上后面的,类似如下代码 //首字母大写 public static String c ...
- SSIS -->> Variable
变量的特点: 1)大小写敏感 2)可见范围限制,里层可以看到外层,外层看不到里层的: 在属性窗口开启EvaluateAsExpression选项可以支持expression动态赋值变量
- 【算法题】- 求和等于K子数组
一整数(有正有负)数组,用尽量少的时间计算数组中和为某个整数的所有子数组 public class SumK { public static void main(String[] args) { in ...
- hibernate学习笔记6--Criteria查询方式、完整小练习(开发步骤)
一.Criteria查询方式没有sql语了,因此更加面向对象一些.Criteria是一种比HQL更面向对象的查询方式:Criteria的创建方式: Criteria c = s.createCrite ...
- design pattern及其使用
什么是设计模式? design pattern是一个通用的,可以被重用的关于一个常见的问题的解决方案. 为什么要用设计模式? 引入设计模式的理论基础非常简单.我们每天都会碰到问题.我们可能碰到决定使用 ...
- 51nod1757 大灾变
能想到二分答案+最大流判断是否符合.但是不知道如何建图qaq.参考的是http://blog.csdn.net/fsss_7/article/details/52132046的建图方法 #includ ...
- BZOJ 3295 动态逆序对
调了好久.... 转化成三维偏序,cdq处理. 好像比较快? #include<iostream> #include<cstdio> #include<cstring&g ...
- acdream 1683 村民的怪癖(KMP,经典变形)
Problem Description 娜娜费劲九牛二虎之力终于把糖果吃完了(说好的吃不完呢?骗人,口亨~),于是,缘溪行,忘路之远近.忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤纷,娜娜甚异之 ...