1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> 5 <title>JSON</title> 6 <script type="text/javascript" src="createXHR.js"></script> 7 <script type="text/javascript" src="json_parse.js"></script> 8 <script type="text/javascript" src="test01.js"></script> 9 </head> 10 <body> 11 <div id="contacts"></div> 12 </body> 13 </html>
createXHR.js
1 function createXHR() { 2 if (typeof XMLHttpRequest != "undefined") { 3 return new XMLHttpRequest(); 4 } else if (typeof ActiveXObject != "undefined") { 5 if (typeof arguments.callee.activeXString != "string") { 6 var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp"]; 7 for (var i = 0, len = versions.length; i < len; i++) { 8 try { 9 var xhr = new ActiveXObject(versions[i]); 10 arguments.callee.activeXString = versions[i]; 11 return xhr; 12 } catch (ex) { 13 console.log("异常"); 14 } 15 } 16 } 17 return new ActiveXObject(arguments.callee.activeXString); 18 } else { 19 throw new Error("No XHR object available."); 20 } 21 }
json_parse.js
1 /* 2 json_parse.js 3 2011-03-06 4 5 Public Domain. 6 7 NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. 8 9 This file creates a json_parse function. 10 11 json_parse(text, reviver) 12 This method parses a JSON text to produce an object or array. 13 It can throw a SyntaxError exception. 14 15 The optional reviver parameter is a function that can filter and 16 transform the results. It receives each of the keys and values, 17 and its return value is used instead of the original value. 18 If it returns what it received, then the structure is not modified. 19 If it returns undefined then the member is deleted. 20 21 Example: 22 23 // Parse the text. Values that look like ISO date strings will 24 // be converted to Date objects. 25 26 myData = json_parse(text, function (key, value) { 27 var a; 28 if (typeof value === 'string') { 29 a = 30 /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); 31 if (a) { 32 return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], 33 +a[5], +a[6])); 34 } 35 } 36 return value; 37 }); 38 39 This is a reference implementation. You are free to copy, modify, or 40 redistribute. 41 42 This code should be minified before deployment. 43 See http://javascript.crockford.com/jsmin.html 44 45 USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO 46 NOT CONTROL. 47 */ 48 49 /*members "", "\"", "\/", "\\", at, b, call, charAt, f, fromCharCode, 50 hasOwnProperty, message, n, name, prototype, push, r, t, text 51 */ 52 53 var json_parse = (function () { 54 "use strict"; 55 56 // This is a function that can parse a JSON text, producing a JavaScript 57 // data structure. It is a simple, recursive descent parser. It does not use 58 // eval or regular expressions, so it can be used as a model for implementing 59 // a JSON parser in other languages. 60 61 // We are defining the function inside of another function to avoid creating 62 // global variables. 63 64 var at, // The index of the current character 65 ch, // The current character 66 escapee = { 67 '"': '"', 68 '\\': '\\', 69 '/': '/', 70 b: '\b', 71 f: '\f', 72 n: '\n', 73 r: '\r', 74 t: '\t' 75 }, 76 text, 77 78 error = function (m) { 79 80 // Call error when something is wrong. 81 82 throw { 83 name: 'SyntaxError', 84 message: m, 85 at: at, 86 text: text 87 }; 88 }, 89 90 next = function (c) { 91 92 // If a c parameter is provided, verify that it matches the current character. 93 94 if (c && c !== ch) { 95 error("Expected '" + c + "' instead of '" + ch + "'"); 96 } 97 98 // Get the next character. When there are no more characters, 99 // return the empty string. 100 101 ch = text.charAt(at); 102 at += 1; 103 return ch; 104 }, 105 106 number = function () { 107 108 // Parse a number value. 109 110 var number, 111 string = ''; 112 113 if (ch === '-') { 114 string = '-'; 115 next('-'); 116 } 117 while (ch >= '0' && ch <= '9') { 118 string += ch; 119 next(); 120 } 121 if (ch === '.') { 122 string += '.'; 123 while (next() && ch >= '0' && ch <= '9') { 124 string += ch; 125 } 126 } 127 if (ch === 'e' || ch === 'E') { 128 string += ch; 129 next(); 130 if (ch === '-' || ch === '+') { 131 string += ch; 132 next(); 133 } 134 while (ch >= '0' && ch <= '9') { 135 string += ch; 136 next(); 137 } 138 } 139 number = +string; 140 if (!isFinite(number)) { 141 error("Bad number"); 142 } else { 143 return number; 144 } 145 }, 146 147 string = function () { 148 149 // Parse a string value. 150 151 var hex, 152 i, 153 string = '', 154 uffff; 155 156 // When parsing for string values, we must look for " and \ characters. 157 158 if (ch === '"') { 159 while (next()) { 160 if (ch === '"') { 161 next(); 162 return string; 163 } else if (ch === '\\') { 164 next(); 165 if (ch === 'u') { 166 uffff = 0; 167 for (i = 0; i < 4; i += 1) { 168 hex = parseInt(next(), 16); 169 if (!isFinite(hex)) { 170 break; 171 } 172 uffff = uffff * 16 + hex; 173 } 174 string += String.fromCharCode(uffff); 175 } else if (typeof escapee[ch] === 'string') { 176 string += escapee[ch]; 177 } else { 178 break; 179 } 180 } else { 181 string += ch; 182 } 183 } 184 } 185 error("Bad string"); 186 }, 187 188 white = function () { 189 190 // Skip whitespace. 191 192 while (ch && ch <= ' ') { 193 next(); 194 } 195 }, 196 197 word = function () { 198 199 // true, false, or null. 200 201 switch (ch) { 202 case 't': 203 next('t'); 204 next('r'); 205 next('u'); 206 next('e'); 207 return true; 208 case 'f': 209 next('f'); 210 next('a'); 211 next('l'); 212 next('s'); 213 next('e'); 214 return false; 215 case 'n': 216 next('n'); 217 next('u'); 218 next('l'); 219 next('l'); 220 return null; 221 } 222 error("Unexpected '" + ch + "'"); 223 }, 224 225 value, // Place holder for the value function. 226 227 array = function () { 228 229 // Parse an array value. 230 231 var array = []; 232 233 if (ch === '[') { 234 next('['); 235 white(); 236 if (ch === ']') { 237 next(']'); 238 return array; // empty array 239 } 240 while (ch) { 241 array.push(value()); 242 white(); 243 if (ch === ']') { 244 next(']'); 245 return array; 246 } 247 next(','); 248 white(); 249 } 250 } 251 error("Bad array"); 252 }, 253 254 object = function () { 255 256 // Parse an object value. 257 258 var key, 259 object = {}; 260 261 if (ch === '{') { 262 next('{'); 263 white(); 264 if (ch === '}') { 265 next('}'); 266 return object; // empty object 267 } 268 while (ch) { 269 key = string(); 270 white(); 271 next(':'); 272 if (Object.hasOwnProperty.call(object, key)) { 273 error('Duplicate key "' + key + '"'); 274 } 275 object[key] = value(); 276 white(); 277 if (ch === '}') { 278 next('}'); 279 return object; 280 } 281 next(','); 282 white(); 283 } 284 } 285 error("Bad object"); 286 }; 287 288 value = function () { 289 290 // Parse a JSON value. It could be an object, an array, a string, a number, 291 // or a word. 292 293 white(); 294 switch (ch) { 295 case '{': 296 return object(); 297 case '[': 298 return array(); 299 case '"': 300 return string(); 301 case '-': 302 return number(); 303 default: 304 return ch >= '0' && ch <= '9' ? number() : word(); 305 } 306 }; 307 308 // Return the json_parse function. It will have access to all of the above 309 // functions and variables. 310 311 return function (source, reviver) { 312 var result; 313 314 text = source; 315 at = 0; 316 ch = ' '; 317 result = value(); 318 white(); 319 if (ch) { 320 error("Syntax error"); 321 } 322 323 // If there is a reviver function, we recursively walk the new structure, 324 // passing each name/value pair to the reviver function for possible 325 // transformation, starting with a temporary root object that holds the result 326 // in an empty key. If there is not a reviver function, we simply return the 327 // result. 328 329 return typeof reviver === 'function' ? (function walk(holder, key) { 330 var k, v, value = holder[key]; 331 if (value && typeof value === 'object') { 332 for (k in value) { 333 if (Object.prototype.hasOwnProperty.call(value, k)) { 334 v = walk(value, k); 335 if (v !== undefined) { 336 value[k] = v; 337 } else { 338 delete value[k]; 339 } 340 } 341 } 342 } 343 return reviver.call(holder, key, value); 344 }({'': result}, '')) : result; 345 }; 346 }());
test01.js
1 var xhr = createXHR(); 2 xhr.onreadystatechange = function() { 3 if (xhr.readyState == 4) { 4 if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) { 5 var contacts = JSON.parse(xhr.responseText); 6 var list = document.getElementById("contacts"); 7 for (var i = 0, len = contacts.length; i < len; i++) { 8 var li = document.createElement("li"); 9 li.innerHTML = "<a href=\"mailto:" + contacts[i].email + "\">" + contacts[i].name + "</a>"; 10 list.appendChild(li); 11 } 12 } 13 } 14 }; 15 16 xhr.open("get", "test01.json", true); 17 xhr.send(null);
test01.json
1 [{ 2 "name": "Nicholas C. Zakas", 3 "email": "nicholas@some-domain-name.com" 4 }, { 5 "name": "Jim Smith", 6 "email": "jimsith@some-domain-name.com" 7 }, { 8 "name": "Michael Jones", 9 "email": "mj@some-domain-name.com" 10 }]