您正在阅读此内容的英文版本,因为该语系尚未翻译。 帮助我们翻译此文章吧!
W3C XMLHttpRequest
规范为 XMLHttpRequest
添加HTML语法解析功能, 此前仅支持XML语法解析。该功能允许Web应用程序使用XMLHttpRequest作为解析的DOM。
局限
为了阻止同步使用XMLHttpRequest,HTML在同步模式下不支持使用。并且,只有当responseType属性设置为'document'的情况下,HTML支持才可用。这种限制避免了浪费时间解析HTML,而传统代码在默认模式下使用XMLHttpRequest来检索text/html资源的responseText. 此外,该限制避免了遗留代码的问题,该代码假定Http错误页面(通常具有text/html响应正文)的responseXML为空。
用法
使用XMLHttpRequest将HTML资源恢复为DOM就像使用XMLHttpRequest将XML资源恢复为DOM一样,除了您不能使用同步模式,您必须通过将字符串“document”分配给responseType属性来显式请求文档调用open()之后调用send()之前的XMLHttpRequest对象。
var xhr = new XMLHttpRequest(); xhr.onload = function() { console.log(this.responseXML.title); } xhr.open("GET", "file.html"); xhr.responseType = "document"; xhr.send();
功能检测
方法1
该方法依赖于功能的“强制异步”性质。当你尝试设置一个以“sync”方式打开的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; }
This method is synchronous, does not rely on external assets though it may not be as reliable as method 2 described below since it does not check the actual feature but an indication of that feature.
方法2
检测浏览器是否支持XMLHttpRequest中的HTML解析有两个挑战。首先,检测结果是异步获取的,因为HTML支持仅在异步模式下可用。Second, you have to actually fetch a test document over HTTP, because testing with a data:
URL would end up testing data:
URL support at the same time.
因此,为了检测HTML支持,服务器上需要一个测试HTML文件。这个测试文件很小,格式不是很完整:
<title>&&<</title>
如果文件名为detect.html,以下功能可用于检测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作为唯一参数被异步调用,如果不支持HTML解析,则为false。
字符编码
如果在HTTP Content-Type 头部中声明了字符编码,则使用该字符编码。否则,如果存在字节顺序标记,则使用由字节顺序标记指示的编码。否则,如果有一个meta tag声明文件的前1024个字节中的编码,则使用该编码。否则,文件被解码为UTF-8。
老版本的浏览器中处理HTML
XMLHttpRequest最初只支持XML解析。 HTML解析支持是最近的一个补充。对于较老的浏览器,您甚至可以使用与正则表达式关联的responseText属性,以获取例如已知其ID的HTML元素的源代码:
function getHTML (oXHR, sTargetId) { var rOpen = new RegExp("<(?!\!)\\s*([^\\s>]+)[^>]*\\s+id\\=[\"\']" + sTargetId + "[\"\'][^>]*>" ,"i"), sSrc = oXHR.responseText, aExec = rOpen.exec(sSrc); return aExec ? (new RegExp("(?:(?:.(?!<\\s*" + aExec[1] + "[^>]*[>]))*.?<\\s*" + aExec[1] + "[^>]*[>](?:.(?!<\\s*\/\\s*" + aExec[1] + "\\s*>))*.?<\\s*\/\\s*" + aExec[1] + "\\s*>)*(?:.(?!<\\s*\/\\s*" + aExec[1] + "\\s*>))*.?", "i")).exec(sSrc.slice(sSrc.indexOf(aExec[0]) + aExec[0].length)) || "" : ""; } var oReq = new XMLHttpRequest(); oReq.open("GET", "yourPage.html", true); oReq.onload = function () { console.log(getHTML(this, "intro")); }; oReq.send(null);
Specifications
Specification | Status | Comment |
---|---|---|
XMLHttpRequest | Living Standard | Initial definition |
Browser compatibility
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari (WebKit) |
---|---|---|---|---|---|
Support | 18 | 11.0 (11.0) | 10 | ? | 未实现 (Yes)[1] |
Feature | Android | Firefox Mobile (Gecko) | IE Phone | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|
Support | ? | 11.0 (11.0) | ? | ? | ? |
[1] This feature was implemented in WebKit bug 74626.