www.baike369.com
百科369 > Ajax教程 > XMLHttpRequest(XHR)对象的responseText属性允许多种数据格式

XMLHttpRequest(XHR)对象的responseText属性允许多种数据格式


XMLHttpRequest(XHR)对象的responseText属性允许多种数据格式

属性responseText保存响应体(response body)的原始文本(raw text),但是不包括任何报头。尽管名称的提法有所不同,但XHR实际上是数据格式中立的(neutral)。几乎任何东西都可以传递回来并且把这个属性保存为纯文本、XHTML片段、逗号分隔值、JavaScript或者甚至是二进制编码的数据。


实例

本例提供了一个使用不同格式接收相同响应的方法。

1. 创建ratings.txt和totals.txt文本文件。

2. json.js文件的源代码如下:

/**
 * @class YAHOO.ext.util.JSON
 * Modified version of Douglas Crockford's json.js that doesn't
 * mess with the Object prototype 
 * http://www.json.org/js.html
 * @singleton
 */
var AjaxTCR = {};
AjaxTCR.JSON = new function(){
    var useHasOwn = {}.hasOwnProperty ? true : false;
    // crashes Safari in some instances
    //var validRE = /^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/;
    var pad = function(n) {
        return n < 10 ? '0' + n : n;
    };
    var m = {
        '\b': '\\b',
        '\t': '\\t',
        '\n': '\\n',
        '\f': '\\f',
        '\r': '\\r',
        '"' : '\\"',
        '\\': '\\\\'
    };
    var encodeString = function(s){
        if (/["\\\x00-\x1f]/.test(s)) {
            return '"' + s.replace(/([\x00-\x1f\\"])/g, function(a, b) {
                var c = m[b];
                if(c){
                    return c;
                }
                c = b.charCodeAt();
                return '\\u00' +
                    Math.floor(c / 16).toString(16) +
                    (c % 16).toString(16);
            }) + '"';
        }
        return '"' + s + '"';
    };
    var encodeArray = function(o){
        var a = ['['], b, i, l = o.length, v;
            for (i = 0; i < l; i += 1) {
                v = o[i];
                switch (typeof v) {
                    case 'undefined':
                    case 'function':
                    case 'unknown':
                        break;
                    default:
                        if (b) {
                            a.push(',');
                        }
                        a.push(v === null ? "null" : AjaxTCR.JSON.encode(v));
                        b = true;
                }
            }
            a.push(']');
            return a.join('');
    };
    var encodeDate = function(o){
        return '"' + o.getFullYear() + '-' +
                pad(o.getMonth() + 1) + '-' +
                pad(o.getDate()) + 'T' +
                pad(o.getHours()) + ':' +
                pad(o.getMinutes()) + ':' +
                pad(o.getSeconds()) + '"';
    };
    /**
     * Encodes an Object, Array or other value
     * @param {Mixed} o The variable to encode
     * @return {String} The JSON string
     */
    this.encode = function(o){
        if(typeof o == 'undefined' || o === null){
            return 'null';
        }else if(o instanceof Array){
            return encodeArray(o);
        }else if(o instanceof Date){
            return encodeDate(o);
        }else if(typeof o == 'string'){
            return encodeString(o);
        }else if(typeof o == 'number'){
            return isFinite(o) ? String(o) : "null";
        }else if(typeof o == 'boolean'){
            return String(o);
        }else {
            var a = ['{'], b, i, v;
            for (var i in o) {
                if(!useHasOwn || o.hasOwnProperty(i)) {
                    v = o[i];
                    switch (typeof v) {
                    case 'undefined':
                    case 'function':
                    case 'unknown':
                        break;
                    default:
                        if(b){
                            a.push(',');
                        }
                        a.push(this.encode(i), ':',
                                v === null ? "null" : this.encode(v));
                        b = true;
                    }
                }
            }
            a.push('}');
            return a.join('');
        }
    };
    /**
     * Decodes (parses) a JSON string to an object. If the JSON is invalid, this function throws a SyntaxError.
     * @param {String} json The JSON string
     * @return {Object} The resulting object
     */
    this.decode = function(json){
        // although crockford had a good idea, this line crashes safari in some instances
        //try{
            //if(validRE.test(json)) {
                return eval('(' + json + ')');
           // }
       // }catch(e){
       // }
       // throw new SyntaxError("parseJSON");
    };
}();

3. test.html文件的源代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>XMLHttpRequest(XHR)对象的responseText属性允许多种数据格式实例-www.baike369.com</title>
<script src="json.js" type="text/javascript"></script><script type="text/javascript"> 
function encodeValue(val)
{
  var encodedVal;
  if (!encodeURIComponent)
  {
    encodedVal = escape(val);
    /* fix the omissions */
    encodedVal = encodedVal.replace(/@/g, '%40');
    encodedVal = encodedVal.replace(/\//g, '%2F');
    encodedVal = encodedVal.replace(/\+/g, '%2B');
  }
  else
  {
    encodedVal = encodeURIComponent(val);
    /* fix the omissions */
    encodedVal = encodedVal.replace(/~/g, '%7E');
    encodedVal = encodedVal.replace(/!/g, '%21');
    encodedVal = encodedVal.replace(/\(/g, '%28');
    encodedVal = encodedVal.replace(/\)/g, '%29');
    encodedVal = encodedVal.replace(/'/g, '%27');
  }
  /* clean up the spaces and return */
  return encodedVal.replace(/\%20/g,'+'); 
}
function createXHR()
{
  try { return new XMLHttpRequest(); } catch(e) {}
  try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e) {}
  try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e) {}
  try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) {}
  try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) {}
  return null;
}
function sendRequest(url, payload)
{
  var xhr = createXHR();
  if (xhr)
  {
    xhr.open("GET",url + "?" + payload,true);
    xhr.onreadystatechange = function(){handleResponse(xhr);};
    xhr.send(null);
  }
}
function handleResponse(xhr)
{
  if (xhr.readyState == 4  && xhr.status == 200)
  {
    var responseType = xhr.getResponseHeader("Ajax-Response-Type");
    var responseOutput = document.getElementById("responseOutput");
    var responseText;
    if (responseType != "encoded")
    {
      responseText = xhr.responseText.replace(/<([^>]*)>/g, "&lt;$1&gt;");
      responseText = responseText.replace(/\n/g, "<br/>");
    }
    else
    {
      responseText = xhr.responseText;
    }    
    responseOutput.innerHTML = "<h3>Response Text</h3>" + responseText;
    responseOutput.innerHTML += "<h3>Processed</h3>";
    switch(responseType)
    {
      case "html":
      case "text":
        responseOutput.innerHTML += xhr.responseText;
        break;
      case "xml":
        var xmlDoc = xhr.responseXML;
        var average = xmlDoc.getElementsByTagName("average")[0].firstChild.nodeValue;
        var total = xmlDoc.getElementsByTagName("votes")[0].firstChild.nodeValue;
        var rating = xmlDoc.getElementsByTagName("rating")[0].firstChild.nodeValue;
        responseOutput.innerHTML += "Thank you for voting.  You rated this a <strong>" + rating + "</strong>.  There are <strong>" + total + "</strong> total votes.  The average is <strong>" + average + "</strong>.  You can see the ratings in the <a href='http://ajaxref.com/ch2/ratings.txt' target='_blank'>ratings file</a>.";
        break;
      case "json":
        var jsonObject = AjaxTCR.JSON.decode(xhr.responseText);
        var rating = jsonObject.rating;
        var total = jsonObject.votes;
        var average = jsonObject.average;
        responseOutput.innerHTML += "Thank you for voting.  You rated this a <strong>" + rating + "</strong>.  There are <strong>" + total + "</strong> total votes.  The average is <strong>" + average + "</strong>.  You can see the ratings in the <a href='http://ajaxref.com/ch2/ratings.txt' target='_blank'>ratings file</a>.";
        break;
      case "javascript":
        eval(xhr.responseText);
        break;
      case "encoded":
        responseOutput.innerHTML += decode64(responseText);
        break;
      case "csv":
        var results = xhr.responseText.split(',');
        var rating = results[0];
        var average = results[1];
        var total = results[2];
        responseOutput.innerHTML += "Thank you for voting.  You rated this a <strong>" + rating + "</strong>.  There are <strong>" + total + "</strong> total votes.  The average is <strong>" + average + "</strong>.  You can see the ratings in the <a href='http://ajaxref.com/ch2/ratings.txt' target='_blank'>ratings file</a>.";
        break;
      }
    }
}
function rate(rating, responseType)
{
  /* determine rating value */
  var ratingVal = 0;
  for (var i=0; i < rating.length; i++)
  {
    if (rating[i].checked)
    {
      ratingVal = rating[i].value;
      break;
    }
  }
  responseType = responseType.options[responseType.selectedIndex].text; 
  var url = "http://localhost:8080/PHPCeShi/code.php";
  var payload = "rating=" + encodeValue(ratingVal);
  payload += "&response=" + responseType;
  sendRequest(url, payload);
  return false;
}
function decode64(input) {
  var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  var output = "";
  var chr1, chr2, chr3;
  var enc1, enc2, enc3, enc4;
  var i = 0;
  // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
  input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
  do {
    enc1 = keyStr.indexOf(input.charAt(i++));
    enc2 = keyStr.indexOf(input.charAt(i++));
    enc3 = keyStr.indexOf(input.charAt(i++));
    enc4 = keyStr.indexOf(input.charAt(i++));
    chr1 = (enc1 << 2) | (enc2 >> 4);
    chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
    chr3 = ((enc3 & 3) << 6) | enc4;
    output = output + String.fromCharCode(chr1);
    if (enc3 != 64) {
      output = output + String.fromCharCode(chr2);
    }
    if (enc4 != 64) {
      output = output + String.fromCharCode(chr3);
    }
  } while (i < input.length);
  return output;
}
window.onload = function () 
{ 
  document.ratingForm.onsubmit = function () { return rate(this.rating,this.responseType); };
};</script> 
</head>
<body>
<h3>How do you feel about Ajax?</h3>
<form action="#" method="get" name="ratingForm">
<em>Hate It - </em> [
<input type="radio" name="rating" value="1" /> 1
<input type="radio" name="rating" value="2" /> 2
<input type="radio" name="rating" value="3" /> 3
<input type="radio" name="rating" value="4" /> 4
<input type="radio" name="rating" value="5" /> 5
] <em> - Love It</em>
<label>Response:
<select name="responseType">
  <option>Text</option>
  <option>HTML</option>
  <option>XML</option>
  <option>JSON</option>
  <option>JavaScript</option>
  <option>Encoded</option>
  <option>CSV</option>
</select>
</label>
<input type="submit" value="vote" />
</form>
<br />
<div id="responseOutput">&nbsp;</div>
</body>
</html>

4. code.php文件的源代码如下:

<?php
if (isset($_REQUEST["delay"]) && is_numeric($_REQUEST["delay"]))
  sleep($_REQUEST["delay"]);
/* File to write to */
$theFile = "ratings.txt";
$totalsFile = "totals.txt";
/* pull the user ratings via the query string */
$rating = htmlentities(substr(urldecode(gpc("rating")),0,1024));
$comment = htmlentities(substr(urldecode(gpc("comment")),0,1024));
$response = strtolower(htmlentities(substr(urldecode(gpc("response")),0,1024)));
$error = htmlentities(substr(urldecode(gpc("error")),0,1024));
$callback = htmlentities(substr(urldecode(gpc("callback")),0,1024));
$validdtd = htmlentities(substr(urldecode(gpc("validdtd")),0,1024));
if ($rating == "")
  $rating = 0;
$transport = "XHR";
if ($response == "")
  $response = "html";
/* if error is set, set appropriate header and then return */
if ($error != "")
{
  if ($error == "404")
    header("HTTP/1.1 404 Not Found\n\n");
  else
    header("HTTP/1.1 500 Internal Server Error\n\n");
  exit;
}
/* record the IP address and time */
$userIP =  $_SERVER['REMOTE_ADDR'];
$currentTime = date("M d y h:i:s A");
/* open the file and get the contents */
$filehandle = fopen($theFile, "r");
if ($filehandle)
{
  $data = fread($filehandle, filesize($theFile));
  fclose($filehandle);
}
else
  die('Failed to read file');
/* open the file and write line to the top of the file */    
$filehandle = fopen($theFile, "w+");
if ($filehandle) 
{
  fwrite($filehandle,"$rating\t $transport\t $userIP @ $currentTime\t $comment\n");
  fwrite($filehandle, $data);
  fclose($filehandle);
}
else
  die('Failed to write file');
//get the totals
$votes = $total = $average = 0;
$filehandle = fopen($totalsFile, "r+");
if ($filehandle) 
{
  $line = fgets($filehandle, 4096);
  $tokens = explode("\t", $line);
  if (count($tokens) > 1)
  {
    $votes = $tokens[0] + 1;
    $total = $tokens[1] + $rating;
  }
  fclose($filehandle);
}
else
  die('Failed to read file');
$filehandle = fopen($totalsFile, "w+");
if ($filehandle) 
{
  fwrite($filehandle,"$votes\t$total\n");
  fclose($filehandle);
}
else
  die('Failed to write file');
if ($votes != 0) $average = round(($total/$votes), 2);
// send the right headers
header("Cache-Control: no-cache");
header("Pragma: no-cache");
header("Ajax-Response-Type: $response");
$message = "";
if ($response == "html")
{
  $message = "Thank you for voting.  You rated this a <strong>$rating</strong>.  There are <strong>$votes</strong> total votes.  The average is <strong>$average</strong>.  You can see the ratings in the <a href='http://www.baike369.com/ratings.txt' target='_blank'>ratings file</a>";
}
else if ($response == "text")
{
  $message = "Thank you for voting.  You rated this a $rating.  There are $votes total votes.  The average is $average.";
} 
else if ($response == "csv")
{
  $message = "$rating,$average,$votes";
}    
else if ($response == "encoded")
{
  $msg = "Thank you for voting.  You rated this a <strong>$rating</strong>.  There are <strong>$votes</strong> total votes.  The average is <strong>$average</strong>.  You can see the ratings in the <a href='http://www.baike369.com/ratings.txt' target='_blank'>ratings file</a>";
  $message = base64_encode($msg);
}
else if ($response == "xml")
{
  header("Content-Type: text/xml");
  $message = 
  "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>
  <!DOCTYPE pollresults SYSTEM \"ratings.dtd\">
    <pollresults>
    <rating>$rating</rating>
    <average>$average</average>
    <votes id=\"votes\"";
  if ($validdtd == "false")
    $message .= " name=\"votes\"";
  $message .= ">$votes</votes>
  </pollresults>
  " ;
}
else if ($response == "xmlbad")
{
  header("Content-Type: text/xml");
  $message = 
  "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n
    <pollresults>\r\n
    <rating>$rating</rating>\r\n
    <average>$average\r\n
    <votes>$votes</votes>\r\n
    </pollresults>\r\n
  " ;
}
else if ($response == "json")
{
  require_once('JSON.php');
  $json = new Services_JSON();
  $jsonResponse = new ResponseData();
  $jsonResponse->rating = $rating;
  $jsonResponse->votes = $votes;
  $jsonResponse->average = $average;
  $message = $json->encode($jsonResponse);
}
else if ($response == "javascript")
{
  $message = "
    var responseOutput = document.getElementById(\"responseOutput\");
    responseOutput.innerHTML += 'Thank you for voting.  You rated this a <strong>$rating</strong>.  There are <strong>$votes</strong> total votes.  The average is <strong>$average</strong>.  You can see the ratings in the <a href=\"http://www.baike369.com/ratings.txt\" target=\"_blank\">ratings file</a>';
  ";
}
echo $message;
/* Helper functions */
function gpc($name)
{
  if (isset($_GET[$name]))
    return $_GET[$name];
  else if (isset($_POST[$name]))
    return $_POST[$name];
  else if (isset($_COOKIE[$name]))
    return $_COOKIE[$name];
  else
    return "";
}
class ResponseData
{
  public $average = 0;
  public $rating = 0;
  public $votes = 0;
  public $total = 0;
}
?>

5. 显示效果如下:

XMLHttpRequest(XHR)对象的responseText属性允许多种数据格式

responseText保存的是来自服务器的原始的、未经处理过的响应,这可能是我们所能想像到的任何形式的文本格式。


提示

尽管Ajax在数据格式上是中立的,但它在字符集上并不是这样。在大多数XHR实现中,UTF-8是默认的字符编码。

Copyright© 2011-2016 www.baike369.com All Rights Reserved