From 33058f2b292b3a581333bdfb21b8f671898c5060 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:40:17 -0500 Subject: initial commit --- files/zh-cn/html_in_xmlhttprequest/index.html | 86 +++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 files/zh-cn/html_in_xmlhttprequest/index.html (limited to 'files/zh-cn/html_in_xmlhttprequest') diff --git a/files/zh-cn/html_in_xmlhttprequest/index.html b/files/zh-cn/html_in_xmlhttprequest/index.html new file mode 100644 index 0000000000..77d9eb0822 --- /dev/null +++ b/files/zh-cn/html_in_xmlhttprequest/index.html @@ -0,0 +1,86 @@ +--- +title: HTML in XMLHttpRequest +slug: HTML_in_XMLHttpRequest +--- +

W3C XMLHttpRequest规范添加了XMLHttpRequest对象对HTML解析的支持(原本只支持XML解析).这项特性允许开发者使用XMLHttpRequest来获取一个HTML资源经过解析后的DOM对象.

+

限制

+

为了避免用户使用XMLHttpRequest的同步模式,HTML解析被设计为只支持异步模式.而且,只有当responseType属性被设置为"document"时,HTML解析才会开启.这种限制是为了避免当用户只需要获取 text/html类型资源的responseText属性时浏览器做无用的HTML解析而浪费时间.另外,该限制也同样可以避免在HTTP错误页面(通常是text/html类型的响应)中responseXML属性为空的情况.

+

用法

+

使用XMLHttpRequest时,把HTML资源作为DOM检索和把XML资源作为DOM检索的区别只有两点:1. 不可以使用同步模式. 2. 请求一个文档时,在调用open()方法之后,send()方法之前,必须明确的指定 XMLHttpRequest对象的responseType属性为字符串"document".

+
var xhr = new XMLHttpRequest();
+xhr.onload = function() {
+  alert(this.responseXML.title);
+}
+xhr.open("GET", "file.html");
+xhr.responseType = "document";
+xhr.send();
+
+

特性检测

+

方法1

+

此方法依赖于该特性的限制之一,即"强制异步模式".如果在同步模式中将"document"赋值给XMLHttpRequest对象的responseType属性,浏览器将会抛出异常.

+
function HTMLinXHR() {
+  if (!window.XMLHttpRequest)
+    return false;
+  var req = new window.XMLHttpRequest();
+  req.open('GET', window.location.href, false);
+  try {
+    req.responseType = 'document';
+  } catch(e) {
+    return true;
+  }
+  return false;
+}
+
+
+

{{ JSFiddleLink('HTcKP/1/') }}

+

该方法是同步执行的,并且不需要依赖任何外部资源.但是,由于该方法是间接的检测浏览器是否支持XMLHttpRequest对象的HTML解析特性,所以下面的检测方法2可能更加直接更加可靠一点.

方法2

+

如何准确的检测浏览器是否支持XMLHttpRequest中的HTML解析有两个难点.首先,检测的结果只能在异步模式中获得,因为HTML解析只支持异步模式.其次,你必须真实的通过HTTP协议获取一个文件, 因为,如果使用data:URL,测试会因浏览器是否支持data:URL而受到影响.

+

因此,要检测浏览器是否支持XMLHttpRequest中的HTML解析,需要在服务器上放置一个测试用的HTML文件,该测试文件体积较小,并且不是格式良好的XML文件:

+
<title>&amp;&<</title>
+

如果该文件被命名为detect.html, 那么下面的函数可以用来检测浏览器是否支持XMLHttpRequest中的HTML解析:

+
function detectHtmlInXhr(callback) {
+  if (!window.XMLHttpRequest) {
+    window.setTimeout(function() { callback(false); }, 0);
+    return;
+  }
+  var done = false;
+  var xhr = new window.XMLHttpRequest();
+  xhr.onreadystatechange = function() {
+    if (this.readyState == 4 && !done) {
+      done = true;
+      callback(!!(this.responseXML && this.responseXML.title && this.responseXML.title == "&&<"));
+    }
+  }
+  xhr.onabort = xhr.onerror = function() {
+    if (!done) {
+      done = true;
+      callback(false);
+    }
+  }
+  try {
+    xhr.open("GET", "detect.html");
+    xhr.responseType = "document";
+    xhr.send();
+  } catch (e) {
+    window.setTimeout(function() {
+      if (!done) {
+        done = true;
+        callback(false);
+      }
+    }, 0);
+  }
+}
+
+

参数callback是一个函数,如果浏览器支持HTML解析,那么该函数被异步调用的时候,true会作为唯一的参数传给callback,不支持的话,false 会作为唯一的参数传给callback.

+

{{ JSFiddleLink }}('xfvXR/1/')

字符编码

+

如果HTTP响应头Content-Type字段定义了字符的编码类型, 那么文档的编码类型将指定为该编码. 否则, 如果文档存在BOM(byte order mark), 那么该BOM所表示的编码将会被使用. 再否则, 如果文档的前1024个字节中存在meta 元素,并且指定了文档的编码类型,那么该编码将会被使用.如果这些都没有指定,那么文件将会按UTF-8编码识别.

+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari (WebKit)
Support 18 11 --- --- {{ compatno() }}
(535.14)
+
+
Feature Android Firefox Mobile (Gecko) IE Phone Opera Mobile Safari Mobile
Support --- 11 --- --- ---
+
+

规范

+ +

{{ languages({"ja":"ja/HTML_in_XMLHttpRequest","en":"en/HTML_in_XMLHttpRequest"}) }}

-- cgit v1.2.3-54-g00ecf