www.baike369.com
百科369 > Ajax教程 > XMLHttpRequest(XHR)对象管理MIME类型

XMLHttpRequest(XHR)对象管理MIME类型


XMLHttpRequest(XHR)对象管理MIME类型

对于Ajax应用程序,任何调用的服务器端代码都要正确地设置返回数据的MIME类型。如果XHR对象接收到数据流的Content-type报头没有设置为text/xml,就不应该尝试来解析和填充responseXML属性。如果这种情况发生了,并且继续以任何方式尝试访问属性和完成DOM操作,那么将产生一个JavaScript异常。如果正在获得的的确是特殊MIME类型(像text/xml)的内容,并且因为某些原因而不能在服务器端完成正确设置,而在Firefox和Opera中,有可能通过使用overrideMimeType()方法来进行调整。

在发送请求之前,将这种方法设置用于指明所期望的MIME类型,并且不管其类型是什么,将总是把响应处理为指定的MIME类型:

var xhr = createXHR();
if (xhr){
  xhr.open("GET", url, true);
  xhr.overrideMimeType('text/xml');
  xhr.onreadystatechange = function(){handleResponse(xhr);};
  xhr.send(null);
}

在这里的通信跟踪显示用text/plain格式向浏览器传递内容,该格式随后被text/xml格式覆盖,以便可以解析其内容。

我们可能想知道这种指定方法的价值,典型情况下,需要通过客户端JavaScript来负责格式化将要处理的数据包。抱歉的是,合适的MIME类型的用法并不是主要问题,因为很多服务器端开发人员已经对这个问题有足够的重视。该问题的主要原因还是在浏览器上,特别是Internet Explorer,在它们对待不正确的MIME类型上,显得太过于宽容了,这样开发人员通常不会强制得到正确细节。IE通常会尽快忽略MIME类型,而不会通过查看响应包来决定它是什么类型,也不会支持任何遇到的Content-type报头值。举一个例子,我们可以把一个文件当作text/plain格式,但是如果在文件的前面几行中存在某些HTML标记,那么IE就会把它呈现成HTML,而更符合规范的浏览器将不会这么做,它们会正确地把文件处理成文本(text)。

在Web服务器上或者在程序中,MIME类型设置不正确已经导致了大量“在浏览器X中可以工作但在浏览器Y中不能工作”的错误,包括某些常见的像Flash内容在不同浏览器中处理结果不同等。如果在Ajax应用程序的服务器端得到这一特定细节,就可以避免编程的痛苦和需要像overrideMimeType()这样的方法了。


实例

一个关于overrideMimeType()方法的例子。

1. 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)对象管理MIME类型实例-www.baike369.com</title>
<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(param, checkOverride)
{
  var url = "http://www.baike369.com/code.php?name=" + encodeValue(param);
  var xhr = createXHR();
  if (xhr)
  {
    if (checkOverride && typeof xhr.overrideMimeType == 'undefined'){
      alert("Sorry, this example only works in browsers that support overrideMimeType.");
      return;
    }
    xhr.open("GET", url, true);
    if (checkOverride){
      xhr.overrideMimeType('text/xml');
    }
    xhr.onreadystatechange = function(){handleResponse(xhr);};
    xhr.send(null);
  }
}
function handleResponse(xhr)
{
  if (xhr.readyState == 4  && xhr.status == 200)
  {
    xmlstr = xhr.responseXML;
    var message = xmlstr.getElementsByTagName("message")[0].firstChild.nodeValue;
    var responseOutput = document.getElementById("responseOutput");
    responseOutput.innerHTML = unescape(message);
    responseOutput.style.display = "";    
  }
}
function sendName(requestName, checkOverride)
{
  if (requestName.value === "")
  {
    alert("Please enter your name");
    return false;
  }
  else
  {
    sendRequest(requestName.value, checkOverride.checked);
  }
  return false;
}
window.onload = function () 
{ 
  document.requestForm.requestButton.onclick = function () { sendName(this.form.requestName, this.form.checkOverride); };
};</script> 
</head>
<body>
<form action="#" name="requestForm">
<label>Enter your name:  <input type="text" id="requestName" /></label>
<input type="checkbox" id="checkOverride" name="checkOverride" checked="checked" /> Override Mime Type&nbsp;<input type="button" name="requestButton" value="OK" />
</form>
<br /><br />
<div id="responseOutput" style="display:none;">&nbsp;</div>
</body>
</html>

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

<?php
header("Cache-Control: no-cache");
header("Pragma: no-cache");
header("Content-Type: text/plain");
$name = $_GET["name"];
$datemsg =  "Hello World to " . rawurlencode($name) ." at ". date("h:i:s A");
echo <<< END_OF_FILE
  <hello>
    <message id="date">$datemsg</message>
  </hello>
END_OF_FILE
?>

3. 显示效果如下:

XMLHttpRequest(XHR)对象管理MIME类型

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