资讯专栏INFORMATION COLUMN

关于ajax,json以及jsonp

alighters / 3041人阅读

摘要:中间部分由或多个以,分隔的关键字值对构成,关键字字符串和值之间以分隔数组结构以开始,结束。

Q:AJAX以何种格式来交换数据?跨域的需求如何解决?

A:用JSON来传数据,靠JSONP来跨域(具体参见下文)

AJAX 创建对象

AJAX = Asynchronous(英[eɪˈsɪŋkrənəs]) JavaScript and XML(异步的 JavaScript 和 XML)。

XMLHttpRequest 用于在后台与服务器交换数据。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

创建兼容对象

所有现代浏览器均支持 XMLHttpRequest 对象(IE5 和 IE6 使用 ActiveXObject)。

// 创建 XMLHttpRequest 对象
var xmlhttp;
if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
// 向服务器发送请求
// 当使用 async=true 时,请规定在响应处于 onreadystatechange 事件中的就绪状态时执行的函数
// async=false 时,请不要编写 onreadystatechange 函数 - 把代码放到 send() 语句后面即可
xmlhttp.onreadystatechange=function(){
  if (xmlhttp.readyState==4 && xmlhttp.status==200){
    // 来自服务器的响应 responseText:字符串形式 responseXML:XML形式
    document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
  }
}
xmlhttp.open("GET","test1.txt",true);
xmlhttp.send();
发送请求 XMLHttpRequest 方法

open(method,url,async)

method:请求的类型;GET 或 POST
url:文件在服务器上的地址(该文件可以是任何类型的文件或服务器脚本文件)
async:true(异步)或 false(同步)

send(string)

string:仅用于 POST 请求

GET 还是 POST?

与 POST 相比,GET 更简单也更快,并且在大部分情况下都能用。
然而,在以下情况中,请使用 POST 请求:
无法使用缓存文件(更新服务器上的文件或数据库)
向服务器发送大量数据(POST 没有数据量限制)
发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠

避免得到的是缓存的结果,向URL添加一个唯一的 ID

xmlhttp.open("GET","demo_get.asp?t=" + Math.random(),true);

希望通过 GET 方法发送信息,请向 URL 添加信息

xmlhttp.open("GET","demo_get2.asp?fname=Bill&lname=Gates",true);

需要像 HTML 表单那样 POST 数据,请使用 setRequestHeader() 来添加 HTTP 头。然后在 send() 方法中规定您希望发送的数据

// 向请求添加 HTTP 头。
// setRequestHeader(header,value)
// header: 规定头的名称 value: 规定头的值
xmlhttp.open("POST","ajax_test.asp",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("fname=Bill&lname=Gates");
服务器响应

XMLHttpRequest 对象的 responseText 或 responseXML 属性

responseText:字符串形式
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
responseXML:XML形式
// 请求 books.xml 文件,并解析响应   
xmlDoc=xmlhttp.responseXML;
txt="";
x=xmlDoc.getElementsByTagName("ARTIST");
for (i=0;i";
  }
document.getElementById("myDiv").innerHTML=txt;    
readyState

当请求被发送到服务器时,我们需要执行一些基于响应的任务。
readyState 属性存有 XMLHttpRequest 的状态信息。
每当 readyState 改变时,就会触发 onreadystatechange 事件。

XMLHttpRequest 对象的三个重要的属性

onreadystatechange

存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。

readyState

存有 XMLHttpRequest 的状态。从0到4发生变化。(一共被触发 5 次)
0: 请求未初始化
1: 服务器连接已建立
2: 请求已接收
3: 请求处理中
4: 请求已完成,且响应已就绪

status

200: "OK"
404: 未找到页面

使用 Callback 函数

callback 函数是一种以参数形式传递给另一个函数的函数

JSON

JavaScript 对象表示法(JavaScript Object Notation)
是存储和交换文本信息的语法。类似 XML,比XML更小、更快,更易解析。
JSON有六种类型的值:对象,数组,字符串,数字,布尔值和特殊值null。

JSON 语法规则

数据在名称/值对中
数据由逗号分隔
花括号保存对象
方括号保存数组

JSON具有两种结构:对象,数组

对象结构以”{”大括号开始,以”}”大括号结束。中间部分由0或多个以”,”分隔的”key(关键字)/value(值)”对构成,关键字字符串和值之间以”:”分隔

{
    key1:value1,
    key2:value2,
    ...
}

数组结构以”[”开始,”]”结束。中间由0或多个以”,”分隔的值列表组成

[
   {
       key1:value1,
       key2:value2,
      ...
   },
   {
       key1:value1,
       key2:value2,
      ...
   },
]

JSON的解析与序列化

JSON对象(ECMAScript 5中添加的, 早期JSON解析基本都使用javascript的eval()函数。但是eval有一些性能和安全上的缺点,ECMAScript对解析JSON对象进 行了规范,定义了全局对象JSON,支持的浏览器有标准浏览器和IE8+。对于不支持的浏览器可以引入json2.js文件。)有stringify与parse这两个方法。

JSON.stringify

将javascript对象序列化为JSON格式的字符串

JSON.stringify(ob,filter,indent)包含三个参数,通常我们在使用的时候只带第一个参数,来返回字符串。

ob:要转化成JSON字符串的对象,数组,原始值。

filter:是一个可选的参数,通常是一个函数,用来在字符串化前对值做一些替换。也可以是一个数组,包含哪些需要字符串化的属性名。就是用来过滤的。

// 第二个参数是数组过滤器
var oJson = { name: "hum", age: 20, sex: 1};
console.log(JSON.stringify(oJson, ["age", "sex"])); 
// {"age":20,"sex":1}

// 第二个参数是函数过滤器
// 如果该参数是函数,则它是一个替换函数,该函数会在每一个需要字符串化的对象上调用。
// 这个函数的第一个参数是该对象中的属性名或数组的序号,第二个则是值本身。
// 函数的返回值会替换掉需要字符串化的值,如果函数返回undefined或没有任何的返回值,则会在字符串化的时候忽略这个值。
var oJson = { name: "hum", age: 26, sex: 1, love: ["swing", "jump"]};
console.log(JSON.stringify(oJson, function(k, v){
    switch (k){
        case "age":
            return v > 20 ? "成年": "未成年";
        case "love":
            return v.join(",");
        case "sex":
            return undefined;
        default :
            return v;
    }
})); 
// {"name":"hum","age":"成年","love":"swing,jump"}

indent:也是一个可选参数,在需要输出格式化的可阅读的代码时,使用indent参数来指定用来缩进的字符串或空格。如果省略该参数,返回的字符串将不带任何的额外的空格,这样输出的值很难阅读。就是用来格式化的。

JSON.parse

JSON.parse用来解析json格式的字符串(返回一个对象,数组或原始值)
JSON.parse(s,reviver)包含两个参数

s:要解析的字符串

reviver:用来转换解析值得可选函数

通常使用只使用第一个参数,可选参数reviver,主要是在返回解析值之前,对其进行过滤或后期处理。
reviver函数会在从s中解析的每个原始值调用一次。
调用reviver函数是带有两个参数,第一个属性名(对象的属性名或是转换成字符串的数组序号),第二个参数是对象的属性或是数组的元素值。
reviver函数会作为包含原始值的对象/数组的方法来调用。
reviver函数的返回值会成为属性的新值,如果reviver返回第二个参数,则属性不变。
如果reviver返回undefined或不凡会任何值,则会从对象或是数组中删除属性。

var oJson = { name: "hum", age: 26, sex: 1, love: ["swing", "jump"], birthday: "1988-01-12"};
var sJson = JSON.stringify(oJson);
console.log(sJson);
//{"name":"hum","age":26,"sex":1,"love":["swing","jump"],"birthday":"1988-01-12"}
console.log(JSON.parse(sJson));
console.log(JSON.parse(sJson, function (k, v) {
    if(k == "birthday"){ // 返回日期对象
        return new Date(v);
    }else if(k == "sex"){ // sex不在了
        return undefined;
    }else{
        return v;
    }
}));
JSON格式化工具

http://www.runoob.com/jsontool

JSONP

Jsonp(JSON with Padding) 是 json 的一种"使用模式",可以让网页从别的域名(网站)那获取资料,即跨域读取数据。

JSONP是怎么产生的?

1、众所周知,Ajax直接请求普通文件存在跨域无权限访问的问题(原因参见 同源策略-web脚本安全)

2、但是,HTML的

阅读需要支付1元查看
<