浏览器可以向服务器做出一个HTTP请求,服务器会返回页面,并随之返回另外一些只有浏览器能看到的元数据。
1、从一个URL开始:
var url ="http://someserver.com/data.json";
2、创建一个请求对象:
var request= new XMLHttpRequest();
3、告诉这个请求对象我们想干嘛:
request.open("GET",url);
4、浏览器也可以采用同样的方式通过HTTP从web服务器获取数据。
建立处理程序:
request.οnlοad=function(){
if(request.status==200){
alert("data received!");
<!--获取的数据可以在request对象的responseText属性中找到-->
<!--alert(request.responseText);-->
}
};
5、告诉请求对象去获取数据:
request.send(null);
---------------------------
关于JSON:
刚开发XMLHttpRequest时,XML是大家交换数据采用的方法,现在更多的是JSON。
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于JavaScript(Standard ECMA-262 3rd Edition - December 1999)的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成。
使用JSON:
<!--一个完整的Movie对象-->
var movie=new Movie("Plan 9","Cult Classic",2,["3:00pm","7:00pm"]);
<!--转换为JSON串格式-->
var jsonstring=JSON.stringify(movie);
alert(jsonstring);
<!--转换回对象-->
var jsonMovieObject=JSON.parse(jsonstring);
alert("JSON movie is "+jsonMovieObject.title);
JSON和XML比较
JSON和XML的可读性可谓不相上下,一边是简易的语法,一边是规范的标签形式,很难分出胜负。
XML天生有很好的扩展性;XML有丰富的编码工具,比如Dom4j、JDom等;XML的解析方式有两种:一是通过文档模型解析,另外一种方法是遍历节点(document 以及
childNodes)。
JSON具有简单直观的格式;可以直接与JavaScript、Python等语言中的对象兼容;作为数据包格式传输的时候具有更高的效率(因为JSON不像XML有闭合标签,节省很多字节)。
实例比较:
XML
<?xmlversion="1.0"encoding="utf-8"?>
<country>
<name>中国</name>
<province>
<name>黑龙江</name>
<cities>
<city>哈尔滨</city>
<city>大庆</city>
</cities>
</province>
<province>
<name>广东</name>
<cities>
<city>广州</city>
<city>深圳</city>
<city>珠海</city>
</cities>
</province>
<province>
<name>台湾</name>
<cities>
<city>台北</city>
<city>高雄</city>
</cities>
</province>
<province>
<name>新疆</name>
<cities>
<city>乌鲁木齐</city>
</cities>
</province>
</country>
JSON
{
"name":"中国",
"province":[
{
"name":"黑龙江",
"cities":{
"city":["哈尔滨","大庆"]
}
},
{
"name":"广东",
"cities":{
"city":["广州","深圳","珠海"]
}
},
{
"name":"台湾",
"cities":{
"city":["台北","高雄"]
}
},
{
"name":"新疆",
"cities":{
"city":["乌鲁木齐"]
}
}
]
}
--------------------------------
测试本地文件sales.json
window.οnlοad=function(){
var url="http://localhost/sales.json";
var request=new XMLHttpRequest();
request.open("GET",url);
request.οnlοad=function(){
if(request.status==200){
<!--数据加载完成后调用这个函数-->
updateSales(request.responseText);
}
};
request.send(null);
}
function updateSales(responseText){
var salesDiv=document.getElementById("sales");
saleDiv.innerHTML=responseText;
}
调整代码以利用JSON:
function updateSales(responseText) {
var salesDiv = document.getElementById("sales");
var sales = JSON.parse(responseText);
for (var i = 0; i < sales.length; i++) {
var sale = sales[i];
var div = document.createElement("div");
div.setAttribute("class", "saleItem");
div.innerHTML = sale.name + " sold " + sale.sales + " gumballs";
salesDiv.appendChild(div);
}
}
-----------------------------------
转向实际服务器,这一次获取的不是静态数据文件,而是从远程服务器动态生成的JSON。
那么需要更新URL,转向实际的URL。
如果只是改了URL,那么运行是失败的!
这是因为跨域了,浏览器不允许这么做。
有两种方法:
1、使用托管文件
2、JSONP获取数据(JSON with padding)
JSONP是一种使用<script>标记获取JSOP对象的方法。可以避免XMLHttpRequest的同源安全问题。
特点就是服务器发回JSON串前,把它包装在一个函数调用中。
指定URL时,在末尾增加一个参数:http://.../?callback=updateSales
更新代码:
/*传入的是一个Javascript对象*/
function updateSales(sales) {
var salesDiv = document.getElementById("sales");
for (var i = 0; i < sales.length; i++) {
var sale = sales[i];
var div = document.createElement("div");
div.setAttribute("class", "saleItem");
div.innerHTML = sale.name + " sold " + sale.sales + " gumballs";
salesDiv.appendChild(div);
}
<!doctype html>
<html lang="en">
<head>
<title>Mighty Gumball</title>
<meta charset="utf-8">
<script src="mightygumball.js"></script>
<link rel="stylesheet" href="mightygumball.css">
</head>
<body>
<h1>Mighty Gumball Sales</h1>
<div id="sales">
</div>
<script src="http://.../?callback=updateSales"></script>
</body>
</html>
---------------------------------------
下面希望显示数据不断更新:
1、html中删除JSONP<script>元素
2、需要建立一个处理程序,每隔几秒做出一个JSONP请求
3、实现JSONP代码
建立一个定时器:
var interval = setInterval(handleRefresh, 3000);
handleRefresh();
function handleRefresh() {
var url = "http://gumball.wickedlysmart.com" +
"?callback=updateSales";
var newScriptElement = document.createElement("script");
newScriptElement.setAttribute("src", url);
newScriptElement.setAttribute("id", "jsonp");
var oldScriptElement = document.getElementById("jsonp");
var head = document.getElementsByTagName("head")[0];
if (oldScriptElement == null) {
head.appendChild(newScriptElement);
}
else {
head.replaceChild(newScriptElement, oldScriptElement);
}
}
replaceChild(new,old)是用新元素替换旧元素,旧元素会从DOM中删除。
处理浏览器缓存问题:
var url = "http://gumball.wickedlysmart.com" +
"?callback=updateSales" +
"&random=" + (new Date()).getTime();
运行后发现出现重复问题了。
还可以在URL末尾增加一个lastreporttime参数,这样只会得到这个时间之后的报告:
var url = "http://gumball.wickedlysmart.com" +
"?callback=updateSales" +
"&lastreporttime=" + lastReportTime +
"&random=" + (new Date()).getTime();
var lastReportTime = 0;
//...
function updateSales(sales) {
var salesDiv = document.getElementById("sales");
for (var i = 0; i < sales.length; i++) {
var sale = sales[i];
var div = document.createElement("div");
div.setAttribute("class", "saleItem");
div.innerHTML = sale.name + " sold " + sale.sales + " gumballs";
//salesDiv.appendChild(div);
if (salesDiv.childElementCount == 0) {
salesDiv.appendChild(div);
}
else {
salesDiv.insertBefore(div, salesDiv.firstChild);
}
}
if (sales.length > 0) {
lastReportTime = sales[sales.length-1].time;
}
}
-------------------------------------------------