学习要点:1.IE 中的 XML、2.DOM2 中的 XML、3.跨浏览器处理 XML
随着互联网的发展,Web 应用程序的丰富,开发人员越来越希望能够使用客户端来操作 XML 技术。而 XML 技术一度成为存储和传输结构化数据的标准。所以,本章就详细探讨一下 JavaScript 中使用 XML 的技术。
对于什么是 XML可以理解成一个微型的结构化的数据库,保存一些小型数据用的。
一、IE中的XML
在统一的正式规范出来以前,浏览器对于 XML 的解决方案各不相同。DOM2 级提出了动态创建 XML DOM 规范,DOM3 进一步增强了 XML DOM。所以,在不同的浏览器实现XML 的处理是一件比较麻烦的事情。
1.1、创建 XMLDOM 对象
IE 浏览器是第一个原生支持 XML 的浏览器,而它是通过 ActiveX 对象实现的。这个对象,只有 IE 有,一般是 IE9 之前采用。微软当年为了开发人员方便的处理 XML,创建了MSXML 库,但却没有让 Web 开发人员通过浏览器访问相同的对象。
var xmlDom = new ActiveXObject('MSXML2.DOMDocument');
PS:在这六个版本中微软只推荐三种:
1.MSXML2.DOMDocument.6.0 最可靠最新的版本
2.MSXML2.DOMDocument.3.0 兼容性较好的版本
3.MSXML2.DOMDocument 仅针对 IE5.5 之前的版本
PS:这三个版本在不同的 windows 平台和浏览器下会有不同的支持,那么为了实现兼容,我们应该考虑这样操作:从 6.0->3.0->备用版本这条路线进行实现。
function createXMLDOM() {
var version = [
'MSXML2.DOMDocument.6.0',
'MSXML2.DOMDocument.3.0',
'MSXML2.DOMDocument'
];
for (var i = 0; i < version.length; i ++) {
try {
var xmlDom = new ActiveXObject(version[i]);
return xmlDom;
} catch (e) {
//跳过
}
}
throw new Error('您的系统或浏览器不支持 MSXML!'); //循环后抛出错误
}
1.2、载入 XML
如果已经获取了 XMLDOM 对象,那么可以使用 loadXML()和 load()这两个方法可以分别载入 XML 字符串或 XML 文件。
xmlDom.loadXML('Lee ');
alert(xmlDom.xml);
PS:loadXML 参数直接就是 XML 字符串,如果想效果更好,可以添加换行符\n。.xml属性可以序列化 XML,获取整个 XML 字符串。
xmlDom.load('test.xml'); //载入一个 XML 文件
alert(xmlDom.xml);
当你已经可以加载了 XML,那么你就可以用之前学习的 DOM 来获取 XML 数据,比如标签内的某个文本。
var user = xmlDom.getElementsByTagName('user')[0]; //获取节点
alert(user.tagName); //获取元素标签
alert(user.firstChild.nodeValue); //获取里的值 Lee
DOM 不单单可以获取 XML 节点,也可以创建。
var email= xmlDom.createElement('email');
xmlDom.documentElement.appendChild(email);
1.3.同步及异步
load()方法是用于服务器端载入 XML 的,并且限制在同一台服务器上的 XML 文件。那么在载入的时候有两种模式:同步和异步。
所谓同步:就是在加载 XML 完成之前,代码不会继续执行,直到完全加载了 XML 再返回。好处就是简单方便、坏处就是如果加载的数据停止响应或延迟太久,浏览器会一直堵塞从而造成假死状态。
xmlDom.async = false; //设置同步,false,可以用 PHP 测试假死
所谓异步:就是在加载 XML 时,JavaScript 会把任务丢给浏览器内部后台去处理,不会造成堵塞,但要配合 readystatechange 事件使用,所以,通常我们都使用异步方式。
xmlDom.async = true; //设置异步,默认
通过异步加载,我们发现获取不到 XML 的信息。原因是,它并没有完全加载 XML 就返回了,也就是说,在浏览器内部加载一点,返回一点,加载一点,返回一点。这个时候,我们需要判断是否完全加载,并且可以使用了,再进行获取输出。
var xmlDom = createXMLDOM();
xmlDom.async = true; //异步,可以不写
xmlDom.onreadystatechange = function () {
if (xmlDom.readyState == 4) { //完全加载了,再去获取 XML
alert(xmlDom.xml);
}
}
xmlDom.load('test.xml'); //放在后面重点体现异步的作用
PS:可以通过 readyState 来了解事件的执行次数,将 load()方法放到最后不会因为代码的顺序而导致没有加载。并且 load()方法必须放在 onreadystatechange 之后,才能保证就绪状态变化时调用该事件处理程序,因为要先触发。用 PHP 来测试,在浏览器内部执行时,是否能操作,是否会假死。
PS:不能够使用 this,不能够用 IE 的事件处理函数,原因是 ActiveX 控件为了预防安全性问题。
PS:虽然可以通过 XML DOM 文档加载 XML 文件,但公认的还是 XMLHttpRequest对象比较好。这方面内容,我们在 Ajax 章节详细了解。
1.4、解析错误
在加载 XML 时,无论使用 loadXML()或 load()方法,都有可能遇到 XML 格式不正确的情况。为了解决这个问题,微软的 XML DOM 提供了 parseError 属性。
if (xmlDom.parseError == 0) {
alert(xmlDom.xml);
} else {
throw new Error('错误行号:' + xmlDom.parseError.line +
'\n 错误代号:' + xmlDom.parseError.errorCode +
'\n 错误解释:' + xmlDom.parseError.reason);
}
二、DOM2中的XML
IE 可以实现了对 XML 字符串或 XML 文件的读取,其他浏览器也各自实现了对 XML处理功能。DOM2 级在 document.implementaion 中引入了 createDocument()方法。IE9、Firefox、Opera、Chrome 和 Safari 都支持这个方法。
2.1、创建 XMLDOM 对象
var xmlDom = document.implementation.createDocument('','root',null); //创建 xmlDom
var user = xmlDom.createElement('user'); //创建 user 元素
xmlDom.getElementsByTagName('root')[0].appendChild(user); //添加到 root 下
var value = xmlDom.createTextNode('Lee'); //创建文本
xmlDom.getElementsByTagName('user')[0].appendChild(value); //添加到 user 下
alert(xmlDom.getElementsByTagName('root')[0].tagName);
alert(xmlDom.getElementsByTagName('user')[0].tagName);
alert(xmlDom.getElementsByTagName('user')[0].firstChild.nodeValue);
PS:由于 DOM2 中不支持 loadXML()方法,所以,无法简易的直接创建 XML 字符串。所以,只能采用以上的做法。
PS:createDocument()方法需要传递三个参数,命名空间,根标签名和文档声明,由于JavaScript 管理命名空间比较困难,所以留空即可。文档声明一般根本用不到,直接 null 即可。命名空间和文档声明留空,表示创建 XMLDOM 对象不需要命名空间和文档声明。
PS:命名空间的用途是防止太多的重名而进行的分类,文档类型表明此文档符合哪种规范,而这里创建 XMLDOM 不需要使用这两个参数,所以留空即可。
2.2、载入 XML
DOM2 只支持 load()方法,载入一个同一台服务器的外部 XML 文件。当然,DOM2 也有 async 属性,来表面同步或异步,默认异步。
//同步情况下
var xmlDom = document.implementation.createDocument('','root',null);
xmlDom.async = false;
xmlDom.load('test.xml');
alert(xmlDom.getElementsByTagName('user')[0].tagName);
//异步情况下
var xmlDom = document.implementation.createDocument('','root',null);
xmlDom.async = true;
addEvent(xmlDom, 'load', function () { //异步直接用 onload 即可
alert(this.getElementsByTagName('user')[0].tagName);
});
xmlDom.load('test.xml');
PS:不管在同步或异步来获取 load()方法只有 Mozilla 的 Firefox 才能支持,只不过新版的 Opera 也是支持的,其他浏览器则不支持。
2.3、DOMParser 类型
由于 DOM2 没有 loadXML()方法直接解析 XML 字符串,所以提供了 DOMParser 类型来创建 XML DOM 对象。IE9、Safari、Chrome 和 Opera 都支持这个类型。
var xmlParser = new DOMParser(); //创建 DOMParser 对象
var xmlStr = 'Lee '; //XML 字符串
var xmlDom = xmlParser.parseFromString(xmlStr, 'text/xml'); //创建 XML DOM 对象
alert(xmlDom.getElementsByTagName('user')[0].tagName); //获取 user 元素标签名
PS:XML DOM 对象是通过 DOMParser 对象中的 parseFromString 方法来创建的,两个参数:XML 字符串和内容类型 text/xml。
2.4、XMLSerializer 类型
由于 DOM2 没有序列化 XML 的属性,所以提供了 XMLSerializer 类型来帮助序列化XML 字符串。IE9、Safari、Chrome 和 Opera 都支持这个类型。
var serializer = new XMLSerializer(); //创建 XMLSerializer 对象
var xml = serializer.serializeToString(xmlDom); //序列化 XML
alert(xml);
2.5、解析错误
在 DOM2 级处理 XML 发生错误时,并没有提供特有的对象来捕获错误,而是直接生成另一个错误的 XML 文档,通过这个文档可以获取错误信息。
var errors = xmlDom.getElementsByTagName('parsererror');
if (errors.length > 0) {
throw new Error('XML 格式有误:' + errors[0].textContent);
}
PS:errors[0].firstChild.nodeValue 也可以使用 errors[0].textContent 来代替。
三、跨浏览器处理XML
如果要实现跨浏览器就要思考几个个问题:1.load()只有 IE、Firefox、Opera 支持,所以无法跨浏览器;2.获取 XML DOM 对象顺序问题,先判断先进的 DOM2 的,然后再去判断落后的 IE;3.针对不同的 IE 和 DOM2 级要使用不同的序列化。4.针对不同的报错进行不同的报错机制。
//首先,我们需要跨浏览器获取 XML DOM
function getXMLDOM(xmlStr) {
var xmlDom = null;
if (typeof window.DOMParser != 'undefined') { //W3C
xmlDom = (new DOMParser()).parseFromString(xmlStr, 'text/xml');
var errors = xmlDom.getElementsByTagName('parsererror');
if (errors.length > 0) {
throw new Error('XML 解析错误:' + errors[0].firstChild.nodeValue);
} } else if (typeof window.ActiveXObject != 'undefined') { //IE
var version = [
'MSXML2.DOMDocument.6.0',
'MSXML2.DOMDocument.3.0',
'MSXML2.DOMDocument'
];
for (var i = 0; i < version.length; i ++) {
try {
xmlDom = new ActiveXObject(version[i]);
} catch (e) {
//跳过
} }
xmlDom.loadXML(xmlStr);
if (xmlDom.parseError != 0) {
throw new Error('XML 解析错误:' + xmlDom.parseError.reason);
} } else {
throw new Error('您所使用的系统或浏览器不支持 XML DOM!');
}
return xmlDom;
}
//其次,我们还必须跨浏览器序列化 XML
function serializeXML(xmlDom) {
var xml = '';
if (typeof XMLSerializer != 'undefined') {
xml = (new XMLSerializer()).serializeToString(xmlDom);
} else if (typeof xmlDom.xml != 'undefined') {
xml = xmlDom.xml;
} else {
throw new Error('无法解析 XML!');
}
return xml;
}
PS:由于兼容性序列化过程有一定的差异,可能返回的结果字符串可能会有一些不同。至于 load()加载 XML 文件则因为只有部分浏览器支持而无法跨浏览器。
JavaScript(XPATH)
学习要点:1.IE 中的 XPath、2.W3C 中的 XPath、3.XPath 跨浏览器兼容
XPath 是一种节点查找手段,对比之前使用标准 DOM 去查找 XML 中的节点方式,大大降低了查找难度,方便开发者使用。但是,DOM3 级以前的标准并没有就 XPath 做出规范;直到 DOM3 在首次推荐到标准规范行列。大部分浏览器实现了这个标准,IE 则以自己的方式实现了 XPath。
一、IE中的Xpath
在 IE8 及之前的浏览器 ,XPath 是采用内置基于 ActiveX 的 XML DOM 文档对象实现的。在每一个节点上提供了两个方法:selectSingleNode()和 selectNodes()。
selectSingleNode()方法接受一个 XPath 模式(也就是查找路径),找到匹配的第一个节点并将它返回,没有则返回 null。
var user = xmlDom.selectSingleNode('root/user'); //得到第一个 user 节点
alert(user.xml); //查看 xml 序列
alert(user.tagName); //节点元素名
alert(user.firstChild.nodeValue); //节点内的值
上下文节点: 我们通过 xmlDom 这个对象实例调用方法,而 xmlDom 这个对象实例其实就是一个上下文节点,这个节点指针指向的是根,也就是 root 元素之前。那么如果我们把这个指针指向 user 元素之前,那么结果就会有所变化。
//通过 xmlDom,并且使用 root/user 的路径
var user = xmlDom.selectSingleNode('root/user');
alert(user.tagName); //user
//通过 xmlDom.documentElement,并且使用 user 路径,省去了 root
var user = xmlDom.documentElement.selectSingleNode('user');
alert(user.tagName); //user
//通过 xmlDom,并且使用 user 路径,省去了 root
var user = xmlDom.selectSingleNode('user');
alert(user.tagName); //找不到了,出错
PS:xmlDom 和 xmlDom.documentElement 都是上下文节点,主要就是定位当前路径查找的指针,而 xmlDom 对象实例的指针就是在最根上。
XPath 常用语法
//通过 user[n]来获取第 n+1 条节点,PS:XPath 其实是按 1 为起始值的
var user = xmlDom.selectSingleNode('root/user[1]');
alert(user.xml);
//通过 text()获取节点内的值
var user = xmlDom.selectSingleNode('root/user/text()');
alert(user.xml);
alert(user.nodeValue);
//通过//user 表示在整个 xml 获取到 user 节点,不关心任何层次
var user = xmlDom.selectSingleNode('//user');
alert(user.xml);
//通过 root//user 表示在 root 包含的层次下获取到 user 节点,在 root 内不关心任何层次
var user = xmlDom.selectSingleNode('root//user');
alert(user.tagName);
//通过 root/user[@id=6]表示获取 user 中 id=6 的节点
var user = xmlDom.selectSingleNode('root/user[@id=6]');
alert(user.xml);
PS:更多的 XPath 语法,可以参考 XPath 手册或者 XML DOM 手册进行参考,这里只提供了最常用的语法。
selectSingleNode()方法是获取单一节点,而 selectNodes()方法则是获取一个节点集合。
var users = xmlDom.selectNodes('root/user'); //获取 user 节点集合
alert(users.length);
alert(users[1].xml);
二.W3C下的XPath
在 DOM3 级 XPath 规范定义的类型中,最重要的两个类型是 XPathEvaluator 和XPathResult。其中,XPathEvaluator 用于在特定上下文对 XPath 表达式求值。
W3C 实现 XPath 查询节点比 IE 来的复杂,首先第一步就是需要得到 XPathResult 对象的实例。得到这个对象实例有两种方法,一种是通过创建 XPathEvaluator 对象执行 evaluate()方法,另一种是直接通过上下文节点对象(比如 xmlDom)来执行 evaluate()方法。
//使用 XPathEvaluator 对象创建 XPathResult
var eva = new XPathEvaluator();
var result = eva.evaluate('root/user', xmlDom, null,
XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
alert(result);
//使用上下文节点对象(xmlDom)创建 XPathResult
var result = xmlDom.evaluate('root/user', xmlDom, null,
XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
alert(result);
相对而言,第二种简单方便一点,但 evaluate 方法有五个属性:1.XPath 路径、2.上下文节点对象、3.命名空间求解器(通常是 null)、4.返回结果类型、5 保存结果的 XPathResult对象(通常是 null)。
对于返回的结果类型,有 10 中不同的类型
PS:上面的常量过于繁重,对于我们只需要学习了解,其实也就需要两个:1.获取一个单一节、2.获取一个节点集合。
1.获取一个单一节点
var result = xmlDom.evaluate('root/user', xmlDom, null,
XPathResult.FIRST_ORDERED_NODE_TYPE, null);
if (result !== null) {
alert(result.singleNodeValue.tagName); //singleNodeValue 属性得到节点对象
}
2.获取节点集合
var result = xmlDom.evaluate('root/user', xmlDom, null,
XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
var nodes = [];
if (result !== null) {
while ((node = result.iterateNext()) !== null) {
nodes.push(node);
}
}
PS:节点集合的获取方式,是通过迭代器遍历而来的,我们保存到数据中就模拟出 IE相似的风格。
三、XPath 跨浏览器兼容
如果要做 W3C 和 IE 的跨浏览器兼容,我们要思考几个问题:1.如果传递一个节点的下标,IE 是从 0 开始计算,W3C 从 1 开始计算,可以通过传递获取下标进行增 1 减 1 的操作来进行。2.独有的功能放弃,为了保证跨浏览器。3.只获取单一节点和节点列表即可,基本可以完成所有的操作。
//跨浏览器获取单一节点
function selectSingleNode(xmlDom, xpath) {
var node = null;
if (typeof xmlDom.evaluate != 'undefined') {
var patten = /\[(\d+)\]/g;
var flag = xpath.match(patten);
var num = 0;
if (flag !== null) {
num = parseInt(RegExp.$1) + 1;
xpath = xpath.replace(patten, '[' + num + ']');
}
var result = xmlDom.evaluate(xpath, xmlDom, null,
XPathResult.FIRST_ORDERED_NODE_TYPE, null);
if (result !== null) {
node = result.singleNodeValue;
} } else if (typeof xmlDom.selectSingleNode != 'undefined') {
node = xmlDom.selectSingleNode(xpath);
}
return node;
}
//跨浏览器获取节点集合
function selectNodes(xmlDom, xpath) {
var nodes = [];
if (typeof xmlDom.evaluate != 'undefined') {
var patten = /\[(\d+)\]/g;
var flag = xpath.match(patten);
var num = 0;
if (flag !== null) {
num = parseInt(RegExp.$1) + 1;
xpath = xpath.replace(patten, '[' + num + ']');
}
var node = null;
var result = xmlDom.evaluate('root/user', xmlDom, null,
XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
if (result !== null) {
while ((node = result.iterateNext()) !== null) {
nodes.push(node);
} } } else if (typeof xmlDom.selectNodes != 'undefined') {
nodes = xmlDom.selectNodes(xpath);
}
return nodes;
}
PS:在传递 xpath 路径时,没有做验证判断是否合法,有兴趣的同学可以自行完成。在XML 还有一个重要章节是 XSLT 和 EX4,由于在使用频率的缘故,我们暂且搁置。
JavaScript(JSON)
学习要点:1.JSON 语法、2.解析和序列化
前两章我们探讨了 XML 的结构化数据,但开发人员还是觉得这种微型的数据结构还是过于烦琐、冗长。为了解决这个问题,JSON 的结构化数据出现了。JSON 是 JavaScript 的一个严格的子集,利用 JavaScript 中的一些模式来表示结构化数据。
一、JSON语法
JSON 和 XML 类型,都是一种结构化的数据表示方式。所以,JSON 并不是 JavaScript独有的数据格式,其他很多语言都可以对 JSON 进行解析和序列化。
JSON 的语法可以表示三种类型的值:
1.简单值:可以在 JSON 中表示字符串、数值、布尔值和 null。但 JSON 不支持 JavaScript
中的特殊值 undefined。
2.对象:顾名思义。
3.数组:顾名思义
简单值
100、"Lee" 这两个量就是 JSON 的表示方法,一个是 JSON 数值,一个是 JSON 字符串。布尔值和 null 也是有效的形式。但实际运用中要结合对象或数组。
对象
JavaScript 对象字面量表示法:
var box = {
name : 'Lee',
age : 100
};
而 JSON 中的对象表示法需要加上双引号,并且不存在赋值运算和分号:
{
"name" : "Lee", //使用双引号,否则转换会出错
"age" : 100
}
数组
JavaScript 数组字面量表示法:
var box = [100, 'Lee', true];
而 JSON 中的数组表示法同样没有变量赋值和分号:
[100, "Lee", true]
一般比较常用的一种复杂形式是数组结合对象的形式:
[
{ "title" : "a", "num" : 1},
{ "title" : "b", "num" : 2},
{ "title" : "c", "num" : 3 }
]
PS:一般情况下,我们可以把 JSON 结构数据保存到一个文本文件里,然后通过XMLHttpRequest 对象去加载它,得到这串结构数据字符串(XMLHttpRequest 对象将在 Aajx章节中详细探讨)。所以,我们可以模拟这种过程。
模拟加载 JSON 文本文件的数据,并且赋值给变量。
var box = '[{"name" : "a","age" : 1},{"name" : "b","age" : 2}]';
PS;上面这短代码模拟了 var box = load('demo.json');赋值过程。因为通过 load 加载的文本文件,不管内容是什么,都必须是字符串。所以两边要加上双引号。
其实 JSON 就是比普通数组多了两边的双引号,普通数组如下:
var box = [{name : 'a', age : 1},{name : 'b', age : 2}];
二、解析和序列化
如果是载入的 JSON 文件,我们需要对其进行使用,那么就必须对 JSON 字符串解析成原生的 JavaScript 值。当然,如果是原生的 JavaScript 对象或数组,也可以转换成 JSON 字符串。
对于讲 JSON 字符串解析为 JavaScript 原生值,早期采用的是 eval()函数。但这种方法既不安全,可能会执行一些恶意代码。
var box = '[{"name" : "a","age" : 1},{"name" : "b","age" : 2}]';
alert(box); //JSON 字符串
var json = eval(box); //使用 eval()函数解析
alert(json); //得到 JavaScript 原生值
ECMAScript5 对解析 JSON 的行为进行规范,定义了全局对象 JSON。支持这个对象的浏览器有 IE8+、Firefox3.5+、Safari4+、Chrome 和 Opera10.5+。不支持的浏览器也可以通过一个开源库 json.js 来模拟执行。JSON 对象提供了两个方法,一个是将原生 JavaScript 值转换为 JSON 字符串:stringify();另一个是将 JSON 字符串转换为 JavaScript 原生值:parse()。
var box = '[{"name" : "a","age" : 1},{"name" : "b","age" : 2}]'; //特别注意,键要用双引号
alert(box);
var json = JSON.parse(box); //不是双引号,会报错
alert(json);
var box = [{name : 'a', age : 1},{name : 'b', age : 2}]; //JavaScript 原生值
var json = JSON.stringify(box); //转换成 JSON 字符串
alert(json); //自动双引号
在序列化 JSON 的过程中,stringify()方法还提供了第二个参数。第一个参数可以是一个数组,也可以是一个函数,用于过滤结果。第二个参数则表示是否在 JSON 字符串中保留缩进。
var box = [{name : 'a', age : 1, height : 177},{name : 'b', age : 2, height : 188}];
var json = JSON.stringify(box, ['name', 'age'], 4);
alert(json);
PS:如果不需要保留缩进,则不填即可;如果不需要过滤结果,但又要保留缩进,则讲过滤结果的参数设置为 null。如果采用函数,可以进行复杂的过滤。
var box = [{name : 'a', age : 1, height : 177},{name : 'b', age : 2, height : 188}];
var json = JSON.stringify(box, function (key, value) {
switch (key) {
case 'name' :
return 'Mr. ' + value;
case 'age' :
return value + '岁';
default :
return value;
}
}, 4);
alert(json);
PS:保留缩进除了是普通的数字,也可以是字符。
还有一种方法可以自定义过滤一些数据,使用 toJSON()方法,可以将某一组对象里指定返回某个值。
var box = [{name : 'a', age : 1, height : 177, toJSON : function () {
return this.name;
}},{name : 'b',age : 2, height : 188, toJSON : function () {
return this.name;
}}];
var json = JSON.stringify(box);
alert(json);
PS:由此可见序列化也有执行顺序,首先先执行 toJSON()方法;如果应用了第二个过滤参数,则执行这个方法;然后执行序列化过程,比如将键值对组成合法的 JSON 字符串,比如加上双引号。如果提供了缩进,再执行缩进操作。
解析 JSON 字符串方法 parse()也可以接受第二个参数,这样可以在还原出 JavaScript 值的时候替换成自己想要的值。
var box = '[{"name" : "a","age" : 1},{"name" : "b","age" : 2}]';
var json = JSON.parse(box, function (key, value) {
if (key == 'name') {
return 'Mr. ' + value;
} else {
return value;
}
});
alert(json[0].name);
JavaScript(Ajax)
学习要点:1.XMLHttpRequest、2.GET 与 POST、3.封装 Ajax
2005 年 Jesse James Garrett 发表了一篇文章,标题为:“Ajax:A new Approach to WebApplications”。他在这篇文章里介绍了一种技术,用他的话说,就叫:Ajax,是 AsynchronousJavaScript + XML 的简写。这种技术能够想服务器请求额外的数据而无须卸载页面(即刷新),会带来更好的用户体验。一时间,席卷全球。
一.XMLHttpRequest
Ajax 技术核心是 XMLHttpRequest 对象(简称 XHR),这是由微软首先引入的一个特性,其他浏览器提供商后来都提供了相同的实现。在 XHR 出现之前,Ajax 式的通信必须借助一些 hack 手段来实现,大多数是使用隐藏的框架或内嵌框架。
XHR 的出现,提供了向服务器发送请求和解析服务器响应提供了流畅的接口。能够以异步方式从服务器获取更多的信息,这就意味着,用户只要触发某一事件,在不刷新网页的情况下,更新服务器最新的数据。
虽然 Ajax 中的 x 代表的是 XML,但 Ajax 通信和数据格式无关,也就是说这种技术不一定使用 XML。
IE7+、Firefox、Opera、Chrome 和 Safari 都支持原生的 XHR 对象,在这些浏览器中创建 XHR 对象可以直接实例化 XMLHttpRequest 即可。
var xhr = new XMLHttpRequest();
alert(xhr); //XMLHttpRequest
如果是 IE6 及以下,那么我们必须还需要使用 ActiveX 对象通过 MSXML 库来实现。在低版本 IE 浏览器可能会遇到三种不同版本的 XHR 对象,即 MSXML2.XMLHttp、MSXML2.XMLHttp.3.0、MSXML2.XMLHttp.6.0。我们可以编写一个函数。
function createXHR() {
if (typeof XMLHttpRequest != 'undefined') {
return new XMLHttpRequest();
} else if (typeof ActiveXObject != 'undefined') {
var versions = [
'MSXML2.XMLHttp.6.0',
'MSXML2.XMLHttp.3.0',
'MSXML2.XMLHttp'
];
for (var i = 0; i < versions.length; i ++) {
try {
return new ActiveXObject(version[i]);
} catch (e) {
//跳过
}
}
} else {
throw new Error('您的浏览器不支持 XHR 对象!');
}
}
var xhr = new createXHR();
在使用 XHR 对象时,先必须调用 open()方法,它接受三个参数:要发送的请求类型(get、post)、请求的 URL 和表示是否异步。
xhr.open('get', 'demo.php', false); //对于 demo.php 的 get 请求,false 同步
PS:demo.php 的代码如下:
//一个时间
open()方法并不会真正发送请求,而只是启动一个请求以备发送。通过 send()方法进行发送请求,send()方法接受一个参数,作为请求主体发送的数据。如果不需要则,必须填 null。执行 send()方法之后,请求就会发送到服务器上。
xhr.send(null); //发送请求
当请求发送到服务器端,收到响应后,响应的数据会自动填充 XHR 对象的属性。那么一共有四个属性:
接受响应之后,第一步检查 status 属性,以确定响应已经成功返回。一般而已 HTTP 状态代码为 200 作为成功的标志。除了成功的状态代码,还有一些别的:
HTT状态码
状态字符串
说明
200
ok
服务器成功返回了页面
400
Bad Request
语法错误导致服务器不识别
401
Unauthorized
请求需要用户认证
404
Not found
指定的 URL 在服务器上找不到
500
Internal Server Error
服务器遇到意外错误,无法完成请求
503
ServiceUnavailable
由于服务器过载或维护导致无法完成请求
我们判断 HTTP 状态值即可,不建议使用 HTTP 状态说明,因为在跨浏览器的时候,可能会不太一致。
addEvent(document, 'click', function () {
var xhr = new createXHR();
xhr.open('get', 'demo.php?rand=' + Math.random(), false); //设置了同步
xhr.send(null);
if (xhr.status == 200) { //如果返回成功了
alert(xhr.responseText); //调出服务器返回的数据
} else {
alert('数据返回失败!状态代码:' + xhr.status + '状态信息:' + xhr.statusText);
}
});
以上的代码每次点击页面的时候,返回的时间都是时时的,不同的,说明都是通过服务器及时加载回的数据。那么我们也可以测试一下在非 Ajax 情况下的情况,创建一个demo2.php 文件,使用非 Ajax
同步调用固然简单,但使用异步调用才是我们真正常用的手段。使用异步调用的时候,需要触发 readystatechange 事件,然后检测 readyState 属性即可。这个属性有五个值:
值
状态
说明
0
未初始化
尚未调用 open()方法
1
启动
已经调用 open()方法,但尚未调用 send()方法
2
发送
已经调用 send()方法,但尚未接受响应
3
接受
已经接受到部分响应数据
4
完成
已经接受到全部响应数据,而且可以使用
addEvent(document, 'click', function () {
var xhr = new createXHR();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
alert(xhr.responseText);
} else {
alert('数据返回失败!状态代码:' + xhr.status + '状态信息:' + xhr.statusText);
} }
};
xhr.open('get', 'demo.php?rand=' + Math.random(), true);
xhr.send(null);
});
PS:使用 abort()方法可以取消异步请求,放在 send()方法之前会报错。放在 responseText之前会得到一个空值。
二. GET与POST
在提供服务器请求的过程中,有两种方式,分别是:GET 和 POST。在 Ajax 使用的过程中,GET 的使用频率要比 POST 高。
在了解这两种请求方式前,我们先了解一下 HTTP 头部信息,包含服务器返回的响应头信息和客户端发送出去的请求头信息。我们可以获取响应头信息或者设置请求头信息。我们可以在 Firefox 浏览器的 firebug 查看这些信息。
//使用 getResponseHeader()获取单个响应头信息
alert(xhr.getResponseHeader('Content-Type'));
//使用 getAllResponseHeaders()获取整个响应头信息
alert(xhr.getAllResponseHeaders());
//使用 setRequestHeader()设置单个请求头信息
xhr.setRequestHeader('MyHeader', 'Lee'); //放在 open 方法之后,send 方法之前
PS:我们只可以获取服务器返回回来响应头信息,无法获取向服务器提交的请求头信息,自然自定义的请求头,在 JavaScript 端是无法获取到的。
2.1、GET 请求
GET 请求是最常见的请求类型,最常用于向服务器查询某些信息。必要时,可以将查询字符串参数追加到 URL 的末尾,以便提交给服务器。
xhr.open('get', 'demo.php?rand=' + Math.random() + '&name=Koo', true);
通过 URL 后的问号给服务器传递键值对数据,服务器接收到返回响应数据。特殊字符传参产生的问题可以使用 encodeURIComponent()进行编码处理,中文字符的返回及传参,可以讲页面保存和设置为 utf-8 格式即可。
//一个通用的 URL 提交函数
function addURLParam(url, name, value) {
url += (url.indexOf('?') == -1 ? '?' : '&'); //判断的 url 是否有已有参数
url += encodeURIComponent(name) + '=' + encodeURIComponent(value);
alert(url);
return url;
}
PS:当没有 encodeURIComponent()方法时,在一些特殊字符比如“&”,会出现错误导致无法获取。
2.2、POST 请求
POST 请求可以包含非常多的数据,我们在使用表单提交的时候,很多就是使用的 POST传输方式。
xhr.open('post', 'demo.php', true);
而发送 POST 请求的数据,不会跟在 URL 的尾巴上,而是通过 send()方法向服务器提交数据。
xhr.send('name=Lee&age=100');
一般来说,向服务器发送 POST 请求由于解析机制的原因,需要进行特别的处理。因为POST 请求和 Web 表单提交是不同的,需要使用 XHR 来模仿表单提交。
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
PS:从性能上来讲 POST 请求比 GET 请求消耗更多一些,用相同数据比较,GET 最多比 POST 快两倍。
上一节课的 JSON 也可以使用 Ajax 来回调访问。
var url = 'demo.json?rand=' + Math.random();
var box = JSON.parse(xhr.responseText);
2.3、封装Ajax
因为 Ajax 使用起来比较麻烦,主要就是参数问题,比如到底使用 GET 还是 POST;到底是使用同步还是异步等等,我们需要封装一个 Ajax 函数,来方便我们调用。
function ajax(obj) {
var xhr = new createXHR();
obj.url = obj.url + '?rand=' + Math.random();
obj.data = params(obj.data);
if (obj.method === 'get') obj.url = obj.url.indexOf('?') == -1 ?
obj.url + '?' + obj.data : obj.url + '&' + obj.data;
if (obj.async === true) {
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) callback();
};
}
xhr.open(obj.method, obj.url, obj.async);
if (obj.method === 'post') {
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(obj.data);
} else {
xhr.send(null);
}
if (obj.async === false) {
callback();
}
function callback () {
if (xhr.status == 200) {
obj.success(xhr.responseText); //回调
} else {
alert('数据返回失败!状态代码:' + xhr.status + ',
状态信息:' + xhr.statusText);
} } }
//调用 ajax
addEvent(document, 'click', function () { //IE6 需要重写 addEvent
ajax({
method : 'get',
url : 'demo.php',
data : {
'name' : 'Lee',
'age' : 100
},
success : function (text) {
alert(text);
},
async : true
});
});
//名值对编码
function params(data) {
var arr = [];
for (var i in data) {
arr.push(encodeURIComponent(i) + '=' + encodeURIComponent(data[i]));
}
return arr.join('&');
}
PS:封装 Ajax 并不是一开始就形成以上的形态,需要经过多次变化而成。
你可能感兴趣的:(JavaScript(XML))
Long类型前后端数据不一致
igotyback
前端
响应给前端的数据浏览器控制台中response中看到的Long类型的数据是正常的到前端数据不一致前后端数据类型不匹配是一个常见问题,尤其是当后端使用Java的Long类型(64位)与前端JavaScript的Number类型(最大安全整数为2^53-1,即16位)进行数据交互时,很容易出现精度丢失的问题。这是因为JavaScript中的Number类型无法安全地表示超过16位的整数。为了解决这个问
高级编程--XML+socket练习题
masa010
java 开发语言
1.北京华北2114.8万人上海华东2,500万人广州华南1292.68万人成都华西1417万人(1)使用dom4j将信息存入xml中(2)读取信息,并打印控制台(3)添加一个city节点与子节点(4)使用socketTCP协议编写服务端与客户端,客户端输入城市ID,服务器响应相应城市信息(5)使用socketTCP协议编写服务端与客户端,客户端要求用户输入city对象,服务端接收并使用dom4j
Python教程:一文了解使用Python处理XPath
旦莫
Python进阶 python 开发语言
目录1.环境准备1.1安装lxml1.2验证安装2.XPath基础2.1什么是XPath?2.2XPath语法2.3示例XML文档3.使用lxml解析XML3.1解析XML文档3.2查看解析结果4.XPath查询4.1基本路径查询4.2使用属性查询4.3查询多个节点5.XPath的高级用法5.1使用逻辑运算符5.2使用函数6.实战案例6.1从网页抓取数据6.1.1安装Requests库6.1.2代
DIV+CSS+JavaScript技术制作网页(旅游主题网页设计与制作)云南大理
STU学生网页设计
网页设计 期末网页作业 html静态网页 html5期末大作业 网页设计 web大作业
️精彩专栏推荐作者主页:【进入主页—获取更多源码】web前端期末大作业:【HTML5网页期末作业(1000套)】程序员有趣的告白方式:【HTML七夕情人节表白网页制作(110套)】文章目录二、网站介绍三、网站效果▶️1.视频演示2.图片演示四、网站代码HTML结构代码CSS样式代码五、更多源码二、网站介绍网站布局方面:计划采用目前主流的、能兼容各大主流浏览器、显示效果稳定的浮动网页布局结构。网站程
关于城市旅游的HTML网页设计——(旅游风景云南 5页)HTML+CSS+JavaScript
二挡起步
web前端期末大作业 javascript html css 旅游 风景
⛵源码获取文末联系✈Web前端开发技术描述网页设计题材,DIV+CSS布局制作,HTML+CSS网页设计期末课程大作业|游景点介绍|旅游风景区|家乡介绍|等网站的设计与制作|HTML期末大学生网页设计作业,Web大学生网页HTML:结构CSS:样式在操作方面上运用了html5和css3,采用了div+css结构、表单、超链接、浮动、绝对定位、相对定位、字体样式、引用视频等基础知识JavaScrip
HTML网页设计制作大作业(div+css) 云南我的家乡旅游景点 带文字滚动
二挡起步
web前端期末大作业 web设计网页规划与设计 html css javascript dreamweaver 前端
Web前端开发技术描述网页设计题材,DIV+CSS布局制作,HTML+CSS网页设计期末课程大作业游景点介绍|旅游风景区|家乡介绍|等网站的设计与制作HTML期末大学生网页设计作业HTML:结构CSS:样式在操作方面上运用了html5和css3,采用了div+css结构、表单、超链接、浮动、绝对定位、相对定位、字体样式、引用视频等基础知识JavaScript:做与用户的交互行为文章目录前端学习路线
【目标检测数据集】卡车数据集1073张VOC+YOLO格式
熬夜写代码的平头哥∰
目标检测 YOLO 人工智能
数据集格式:PascalVOC格式+YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件)图片数量(jpg文件个数):1073标注数量(xml文件个数):1073标注数量(txt文件个数):1073标注类别数:1标注类别名称:["truck"]每个类别标注的框数:truck框数=1120总框数:1120使用标注工具:labelImg标注
node.js学习
小猿L
node.js node.js 学习 vim
node.js学习实操及笔记温故node.js,node.js学习实操过程及笔记~node.js学习视频node.js官网node.js中文网实操笔记githubcsdn笔记为什么学node.js可以让别人访问我们编写的网页为后续的框架学习打下基础,三大框架vuereactangular离不开node.jsnode.js是什么官网:node.js是一个开源的、跨平台的运行JavaScript的运行
钢筋长度超限检测检数据集VOC+YOLO格式215张1类别
futureflsl
数据集 YOLO 深度学习 机器学习
数据集格式:PascalVOC格式+YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件)图片数量(jpg文件个数):215标注数量(xml文件个数):215标注数量(txt文件个数):215标注类别数:1标注类别名称:["iron"]每个类别标注的框数:iron框数=215总框数:215使用标注工具:labelImg标注规则:对类别进
SpringBlade dict-biz/list 接口 SQL 注入漏洞
文章永久免费只为良心
oracle 数据库
SpringBladedict-biz/list接口SQL注入漏洞POC:构造请求包查看返回包你的网址/api/blade-system/dict-biz/list?updatexml(1,concat(0x7e,md5(1),0x7e),1)=1漏洞概述在SpringBlade框架中,如果dict-biz/list接口的后台处理逻辑没有正确地对用户输入进行过滤或参数化查询(PreparedSta
spring如何整合druid连接池?
惜.己
spring spring junit 数据库 java idea 后端 xml
目录spring整合druid连接池1.新建maven项目2.新建mavenModule3.导入相关依赖4.配置log4j2.xml5.配置druid.xml1)xml中如何引入properties2)下面是配置文件6.准备jdbc.propertiesJDBC配置项解释7.配置druid8.测试spring整合druid连接池1.新建maven项目打开IDE(比如IntelliJIDEA,Ecl
JavaScript 中,深拷贝(Deep Copy)和浅拷贝(Shallow Copy)
跳房子的前端
前端面试 javascript 开发语言 ecmascript
在JavaScript中,深拷贝(DeepCopy)和浅拷贝(ShallowCopy)是用于复制对象或数组的两种不同方法。了解它们的区别和应用场景对于避免潜在的bugs和高效地处理数据非常重要。以下是对深拷贝和浅拷贝的详细解释,包括它们的概念、用途、优缺点以及实现方式。1.浅拷贝(ShallowCopy)概念定义:浅拷贝是指创建一个新的对象或数组,其中包含了原对象或数组的基本数据类型的值和对引用数
遥感影像的切片处理
sand&wich
计算机视觉 python 图像处理
在遥感影像分析中,经常需要将大尺寸的影像切分成小片段,以便于进行详细的分析和处理。这种方法特别适用于机器学习和图像处理任务,如对象检测、图像分类等。以下是如何使用Python和OpenCV库来实现这一过程,同时确保每个影像片段保留正确的地理信息。准备环境首先,确保安装了必要的Python库,包括numpy、opencv-python和xml.etree.ElementTree。这些库将用于图像处理
JavaScript `Map` 和 `WeakMap`详细解释
跳房子的前端
JavaScript 原生方法 javascript 前端 开发语言
在JavaScript中,Map和WeakMap都是用于存储键值对的数据结构,但它们有一些关键的不同之处。MapMap是一种可以存储任意类型的键值对的集合。它保持了键值对的插入顺序,并且可以通过键快速查找对应的值。Map提供了一些非常有用的方法和属性来操作这些数据对:set(key,value):将一个键值对添加到Map中。如果键已经存在,则更新其对应的值。get(key):获取指定键的值。如果键
使用由 Python 编写的 lxml 实现高性能 XML 解析
hunyxv
python 笔记 python xml
转载自:文章lxml简介Python从来不出现XML库短缺的情况。从2.0版本开始,它就附带了xml.dom.minidom和相关的pulldom以及SimpleAPIforXML(SAX)模块。从2.4开始,它附带了流行的ElementTreeAPI。此外,很多第三方库可以提供更高级别的或更具有python风格的接口。尽管任何XML库都足够处理简单的DocumentObjectModel(DOM
切换淘宝最新npm镜像源是
hai40587
npm 前端 node.js
切换淘宝最新npm镜像源是一个相对简单的过程,但首先需要明确当前淘宝npm镜像源的状态和最新的镜像地址。由于网络环境和服务更新,镜像源的具体地址可能会发生变化,因此,我将基于当前可获取的信息,提供一个通用的切换步骤,并附上最新的镜像地址(截至回答时)。一、了解npm镜像源npm(NodePackageManager)是JavaScript的包管理器,用于安装、更新和管理项目依赖。由于npm官方仓库
高性能javascript--算法和流程控制
海淀萌狗
-for,while和do-while性能相当-避免使用for-in循环,==除非遍历一个属性量未知的对象==es5:for-in遍历的对象便不局限于数组,还可以遍历对象。原因:for-in每次迭代操作会同时搜索实例或者原型属性,for-in循环的每次迭代都会产生更多开销,因此要比其他循环类型慢,一般速度为其他类型循环的1/7。因此,除非明确需要迭代一个属性数量未知的对象,否则应避免使用for-i
[数据集][目标检测]汽车头部尾部检测数据集VOC+YOLO格式5319张3类别
FL1623863129
数据集 目标检测 汽车 YOLO
数据集制作单位:未来自主研究中心(FIRC)版权单位:未来自主研究中心(FIRC)版权声明:数据集仅仅供个人使用,不得在未授权情况下挂淘宝、咸鱼等交易网站公开售卖,由此引发的法律责任需自行承担数据集格式:PascalVOC格式+YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件)图片数量(jpg文件个数):5319标注数量(xml文件
idea使用自定义checkstyle.xml配置文件
Gemkey
1.下载插件image.png2.插件安装完后,找到设置中的checkstyle,点击"+",新增自定义规则image.png3.输入描述信息,点击Browse找到对应的文件image.pngimage.png4.可以把active勾上,则使用默认校验规则,点击OK,则可以开始使用自定义规则检测单个文件了image.png
360前端星计划-动画可以这么玩
马小蜗
动画的基本原理定时器改变对象的属性根据新的属性重新渲染动画functionupdate(context){//更新属性}constticker=newTicker();ticker.tick(update,context);动画的种类1、JavaScript动画操作DOMCanvas2、CSS动画transitionanimation3、SVG动画SMILJS动画的优缺点优点:灵活度、可控性、性能
JavaScript中秋快乐!
Q_w7742
javascript 开发语言 ecmascript
我们来实现一个简单的祝福网页~主要的难度在于使用canvas绘图当点击canvas时候,跳出“中秋节快乐”字样,需要注册鼠标单击事件和计时器。首先定义主要函数:初始化当点击canvas之后转到onCanvasClick函数,绘图生成灯笼。functiononCanvasClick(){//事件处理函数context.clearRect(0,0,canvas1.width,canvas1.heigh
Nginx从入门到实践(三)
听你讲故事啊
动静分离动静分离是将网站静态资源(JavaScript,CSS,img等文件)与后台应用分开部署,提高用户访问静态代码的速度,降低对后台应用访问。动静分离的一种做法是将静态资源部署在nginx上,后台项目部署到应用服务器上,根据一定规则静态资源的请求全部请求nginx服务器,达到动静分离的目标。rewrite规则Rewrite规则常见正则表达式Rewrite主要的功能就是实现URL的重写,Ngin
Nginx的使用场景:构建高效、可扩展的Web架构
张某布响丸辣
nginx 前端 架构
Nginx,作为当今最流行的Web服务器和反向代理软件之一,凭借其高性能、稳定性和灵活性,在众多Web项目中扮演着核心角色。无论是个人博客、中小型网站,还是大型企业级应用,Nginx都能提供强大的支持。本文将探讨Nginx的几个主要使用场景,帮助读者理解如何在实际项目中充分利用Nginx的优势。1.静态文件服务对于包含大量静态文件(如HTML、CSS、JavaScript、图片等)的网站,Ngin
前端知识点
ZhangTao_zata
前端 javascript css
下面是一个最基本的html代码body{font-family:Arial,sans-serif;margin:20px;}//JavaScriptfunctionthatdisplaysanalertwhencalledfunctionshowMessage(){alert("Hello!Youclickedthebutton.");}MyFirstHTMLPageWelcometoMyPage
Python精选200Tips:121-125
AnFany
Python200+Tips python 开发语言
Spendyourtimeonself-improvement121Requests-简化的HTTP请求处理发送GET请求发送POST请求发送PUT请求发送DELETE请求会话管理处理超时文件上传122BeautifulSoup-网页解析和抓取解析HTML和XML文档查找单个标签查找多个标签使用CSS选择器查找标签提取文本修改文档内容删除标签处理XML文档123Scrapy-强大的网络爬虫框架示例
maven-assembly-plugin 打包实例
带着二娃去遛弯
1.先在pom.xml文件中添加assembly打包插件org.apache.maven.pluginsmaven-assembly-plugin2.6assembly/assembly.xmlmake-assemblypackagesingle说明:1.需要修改的可能就是descriptors标签下面的打包配置文件目录,指定assembly.xml的路径.2.可以添加多个打包配置文件,进行多种形
【JS】前端文件读取FileReader操作总结
程序员-张师傅
前端 前端 javascript 开发语言
前端文件读取FileReader操作总结FileReader是JavaScript中的一个WebAPI,它允许web应用程序异步读取用户计算机上的文件(或原始数据缓冲区)的内容,例如读取文件以获取其内容,并在不将文件发送到服务器的情况下在客户端使用它。这对于处理图片、文本文件等非常有用,尤其是当你想要在用户界面中即时显示文件内容或进行文件预览时。创建FileReader对象首先,你需要创建一个Fi
小程序通过js控制页面字体颜色属性
祈澈菇凉
需求:当电量少于百分之20的时候,显示电量的字体显示为红色。1:在wxml里面设置属性batStyle:style="{{item.batStyle}}"电量:{{item.battery}}%2:当复合逻辑条件的时候,在js里面carList[i].batStyle="color:red";success:function(res){constcarList=res.data.list;for(
webstorm报错TypeError: this.cliEngine is not a constructor
Blue_Color
点击Details在控制台会显示报错的位置TypeError:this.cliEngineisnotaconstructoratESLintPlugin.invokeESLint(/Applications/RubyMine.app/Contents/plugins/JavaScriptLanguage/languageService/eslint/bin/eslint-plugin.js:97:
创建一个完整的购物商城系统是一个复杂的项目,涉及前端(用户界面)、后端(服务器逻辑)、数据库等多个部分。由于篇幅限制,我无法在这里提供一个完整的系统代码,但我可以分别给出一些关键部分的示例代码,涵盖几
uthRaman
前端 ui 服务器
前端(HTML/CSS/JavaScript)grsyzp.cnHTML页面结构(index.html)html购物商城欢迎来到购物商城JavaScript(Ajax请求商品数据,app.js)javascriptdocument.addEventListener('DOMContentLoaded',function(){fetch('/api/products').then(response=
JVM StackMapTable 属性的作用及理解
lijingyao8206
jvm 字节码 Class文件 StackMapTable
在Java 6版本之后JVM引入了栈图(Stack Map Table)概念。为了提高验证过程的效率,在字节码规范中添加了Stack Map Table属性,以下简称栈图,其方法的code属性中存储了局部变量和操作数的类型验证以及字节码的偏移量。也就是一个method需要且仅对应一个Stack Map Table。在Java 7版
回调函数调用方法
百合不是茶
java
最近在看大神写的代码时,.发现其中使用了很多的回调 ,以前只是在学习的时候经常用到 ,现在写个笔记 记录一下
代码很简单:
MainDemo :调用方法 得到方法的返回结果
[时间机器]制造时间机器需要一些材料
comsci
制造
根据我的计算和推测,要完全实现制造一台时间机器,需要某些我们这个世界不存在的物质
和材料...
甚至可以这样说,这种材料和物质,我们在反应堆中也无法获得......
 
开口埋怨不如闭口做事
邓集海
邓集海 做人 做事 工作
“开口埋怨,不如闭口做事。”不是名人名言,而是一个普通父亲对儿子的训导。但是,因为这句训导,这位普通父亲却造就了一个名人儿子。这位普通父亲造就的名人儿子,叫张明正。 张明正出身贫寒,读书时成绩差,常挨老师批评。高中毕业,张明正连普通大学的分数线都没上。高考成绩出来后,平时开口怨这怨那的张明正,不从自身找原因,而是不停地埋怨自己家庭条件不好、埋怨父母没有给他创造良好的学习环境。
jQuery插件开发全解析,类级别与对象级别开发
IT独行者
jquery 开发 插件 函数
jQuery插件的开发包括两种: 一种是类级别的插件开发,即给
jQuery添加新的全局函数,相当于给
jQuery类本身添加方法。
jQuery的全局函数就是属于
jQuery命名空间的函数,另一种是对象级别的插件开发,即给
jQuery对象添加方法。下面就两种函数的开发做详细的说明。
1
、类级别的插件开发 类级别的插件开发最直接的理解就是给jQuer
Rome解析Rss
413277409
Rome解析Rss
import java.net.URL;
import java.util.List;
import org.junit.Test;
import com.sun.syndication.feed.synd.SyndCategory;
import com.sun.syndication.feed.synd.S
RSA加密解密
无量
加密 解密 rsa
RSA加密解密代码
代码有待整理
package com.tongbanjie.commons.util;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerat
linux 软件安装遇到的问题
aichenglong
linux 遇到的问题 ftp
1 ftp配置中遇到的问题
500 OOPS: cannot change directory
出现该问题的原因:是SELinux安装机制的问题.只要disable SELinux就可以了
修改方法:1 修改/etc/selinux/config 中SELINUX=disabled
2 source /etc
面试心得
alafqq
面试
最近面试了好几家公司。记录下;
支付宝,面试我的人胖胖的,看着人挺好的;博彦外包的职位,面试失败;
阿里金融,面试官人也挺和善,只不过我让他吐血了。。。
由于印象比较深,记录下;
1,自我介绍
2,说下八种基本类型;(算上string。楼主才答了3种,哈哈,string其实不是基本类型,是引用类型)
3,什么是包装类,包装类的优点;
4,平时看过什么书?NND,什么书都没看过。。照样
java的多态性探讨
百合不是茶
java
java的多态性是指main方法在调用属性的时候类可以对这一属性做出反应的情况
//package 1;
class A{
public void test(){
System.out.println("A");
}
}
class D extends A{
public void test(){
S
网络编程基础篇之JavaScript-学习笔记
bijian1013
JavaScript
1.documentWrite
<html>
<head>
<script language="JavaScript">
document.write("这是电脑网络学校");
document.close();
</script>
</h
探索JUnit4扩展:深入Rule
bijian1013
JUnit Rule 单元测试
本文将进一步探究Rule的应用,展示如何使用Rule来替代@BeforeClass,@AfterClass,@Before和@After的功能。
在上一篇中提到,可以使用Rule替代现有的大部分Runner扩展,而且也不提倡对Runner中的withBefores(),withAfte
[CSS]CSS浮动十五条规则
bit1129
css
这些浮动规则,主要是参考CSS权威指南关于浮动规则的总结,然后添加一些简单的例子以验证和理解这些规则。
1. 所有的页面元素都可以浮动 2. 一个元素浮动后,会成为块级元素,比如<span>,a, strong等都会变成块级元素 3.一个元素左浮动,会向最近的块级父元素的左上角移动,直到浮动元素的左外边界碰到块级父元素的左内边界;如果这个块级父元素已经有浮动元素停靠了
【Kafka六】Kafka Producer和Consumer多Broker、多Partition场景
bit1129
partition
0.Kafka服务器配置
3个broker
1个topic,6个partition,副本因子是2
2个consumer,每个consumer三个线程并发读取
1. Producer
package kafka.examples.multibrokers.producers;
import java.util.Properties;
import java.util.
zabbix_agentd.conf配置文件详解
ronin47
zabbix 配置文件
Aliaskey的别名,例如 Alias=ttlsa.userid:vfs.file.regexp[/etc/passwd,^ttlsa:.:([0-9]+),,,,\1], 或者ttlsa的用户ID。你可以使用key:vfs.file.regexp[/etc/passwd,^ttlsa:.: ([0-9]+),,,,\1],也可以使用ttlsa.userid。备注: 别名不能重复,但是可以有多个
java--19.用矩阵求Fibonacci数列的第N项
bylijinnan
fibonacci
参考了网上的思路,写了个Java版的:
public class Fibonacci {
final static int[] A={1,1,1,0};
public static void main(String[] args) {
int n=7;
for(int i=0;i<=n;i++){
int f=fibonac
Netty源码学习-LengthFieldBasedFrameDecoder
bylijinnan
java netty
先看看LengthFieldBasedFrameDecoder的官方API
http://docs.jboss.org/netty/3.1/api/org/jboss/netty/handler/codec/frame/LengthFieldBasedFrameDecoder.html
API举例说明了LengthFieldBasedFrameDecoder的解析机制,如下:
实
AES加密解密
chicony
加密解密
AES加解密算法,使用Base64做转码以及辅助加密:
package com.wintv.common;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Decod
文件编码格式转换
ctrain
编码格式
package com.test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
mysql 在linux客户端插入数据中文乱码
daizj
mysql 中文乱码
1、查看系统客户端,数据库,连接层的编码
查看方法: http://daizj.iteye.com/blog/2174993
进入mysql,通过如下命令查看数据库编码方式: mysql> show variables like 'character_set_%'; +--------------------------+------
好代码是廉价的代码
dcj3sjt126com
程序员 读书
长久以来我一直主张:好代码是廉价的代码。
当我跟做开发的同事说出这话时,他们的第一反应是一种惊愕,然后是将近一个星期的嘲笑,把它当作一个笑话来讲。 当他们走近看我的表情、知道我是认真的时,才收敛一点。
当最初的惊愕消退后,他们会用一些这样的话来反驳: “好代码不廉价,好代码是采用经过数十年计算机科学研究和积累得出的最佳实践设计模式和方法论建立起来的精心制作的程序代码。”
我只
Android网络请求库——android-async-http
dcj3sjt126com
android
在iOS开发中有大名鼎鼎的ASIHttpRequest库,用来处理网络请求操作,今天要介绍的是一个在Android上同样强大的网络请求库android-async-http,目前非常火的应用Instagram和Pinterest的Android版就是用的这个网络请求库。这个网络请求库是基于Apache HttpClient库之上的一个异步网络请求处理库,网络处理均基于Android的非UI线程,通
ORACLE 复习笔记之SQL语句的优化
eksliang
SQL优化 Oracle sql语句优化 SQL语句的优化
转载请出自出处:http://eksliang.iteye.com/blog/2097999
SQL语句的优化总结如下
sql语句的优化可以按照如下六个步骤进行:
合理使用索引
避免或者简化排序
消除对大表的扫描
避免复杂的通配符匹配
调整子查询的性能
EXISTS和IN运算符
下面我就按照上面这六个步骤分别进行总结:
浅析:Android 嵌套滑动机制(NestedScrolling)
gg163
android 移动开发 滑动机制 嵌套
谷歌在发布安卓 Lollipop版本之后,为了更好的用户体验,Google为Android的滑动机制提供了NestedScrolling特性
NestedScrolling的特性可以体现在哪里呢?<!--[if !supportLineBreakNewLine]--><!--[endif]-->
比如你使用了Toolbar,下面一个ScrollView,向上滚
使用hovertree菜单作为后台导航
hvt
JavaScript jquery .net hovertree asp.net
hovertree是一个jquery菜单插件,官方网址:http://keleyi.com/jq/hovertree/ ,可以登录该网址体验效果。
0.1.3版本:http://keleyi.com/jq/hovertree/demo/demo.0.1.3.htm
hovertree插件包含文件:
http://keleyi.com/jq/hovertree/css
SVG 教程 (二)矩形
天梯梦
svg
SVG <rect> SVG Shapes
SVG有一些预定义的形状元素,可被开发者使用和操作:
矩形 <rect>
圆形 <circle>
椭圆 <ellipse>
线 <line>
折线 <polyline>
多边形 <polygon>
路径 <path>
一个简单的队列
luyulong
java 数据结构 队列
public class MyQueue {
private long[] arr;
private int front;
private int end;
// 有效数据的大小
private int elements;
public MyQueue() {
arr = new long[10];
elements = 0;
front
基础数据结构和算法九:Binary Search Tree
sunwinner
Algorithm
A binary search tree (BST) is a binary tree where each node has a Comparable key (and an associated value) and satisfies the restriction that the key in any node is larger than the keys in all
项目出现的一些问题和体会
Steven-Walker
DAO Web servlet
第一篇博客不知道要写点什么,就先来点近阶段的感悟吧。
这几天学了servlet和数据库等知识,就参照老方的视频写了一个简单的增删改查的,完成了最简单的一些功能,使用了三层架构。
dao层完成的是对数据库具体的功能实现,service层调用了dao层的实现方法,具体对servlet提供支持。
&
高手问答:Java老A带你全面提升Java单兵作战能力!
ITeye管理员
java
本期特邀《Java特种兵》作者:谢宇,CSDN论坛ID: xieyuooo 针对JAVA问题给予大家解答,欢迎网友积极提问,与专家一起讨论!
作者简介:
淘宝网资深Java工程师,CSDN超人气博主,人称“胖哥”。
CSDN博客地址:
http://blog.csdn.net/xieyuooo
作者在进入大学前是一个不折不扣的计算机白痴,曾经被人笑话过不懂鼠标是什么,