HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX


准备工作:使用firebug插件支持的console.log()方法(函数)来动态调试HTML文档中的javascript代码。


1。比较console.log() 与 document.write() 在调试时的功能差异:

如果直接以浏览器打开HTML文档,其中的console.log()方法是不会获得执行的,因为浏览器并不直接支持这个方法,需要在浏览器(如Chrome)的开发者工具或者插件(如Firebug)中的控制台模块,以及console模块内,才能执行这个方法;

document.write() 方法不需要额外的开发工具或插件要求,浏览器可以直接执行并且将结果回写至HTML文档内。

两者的运行环境和效果对比请看下面一系列的截图:


HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX_第1张图片



HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX_第2张图片


其它浏览器对于 console.log()document.write() 的支持情况与 FireFox 类似,基本上都是需要在开发者工具中,才能使用 console.log(),这里就不截图了。

下面的图片着重展示如何在 Firebug 中使用 console.log() :


HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX_第3张图片


HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX_第4张图片

2。除了console.log() 外,还可以使用其变体,如 console.info(),console.debug(),console.warn(),console.error() 等等,需要明确指出使用的是哪一个变体,不能省略,否则开发工具或插件默认会使用 console.log(),例如:

console.warn(alert(navigator.userAgent))

这些变体方法之间的差别在于显示代码执行结果信息的详细程度与图标样式,但总体而言差别不大。

另外一个有用的方法是 console.dir(),如果传递给它的参数是用单引号或者双引号包含的字符串,它可以“逐字符”在控制台窗口输出这些字符;如果不是字符串,那么将输出该参数的值,请参考下面2张图片了解差异:


HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX_第5张图片


HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX_第6张图片


需要注意的是,仅 Firebug 对 console.dir() 的支持程度较好,Chrome 的开发者工具无法完整地实现这个方法。但是后者的优点是,在控制台输入脚本代码时,可以自动列出所有用户想要键入的候选对象,即类似搜索引擎与软件开发 IDE 中的自动完成,补全功能:

HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX_第7张图片

当直接修改 HTML 文档中的内容时,可以使用“”字符串对,来注释文档中任意元素,这会导致浏览器在解析的时候忽略被注释的内容;

要注释 script 标签中的多行脚本代码,则需要使用 C 语言风格的注释语法,即

/*”与“*/”字符串对。


3。比较 input 元素的 type 属性几种常见的值

input 元素经常被包含在 HTML 表单,即 form 元素内部,用来获取各种形式的用户输入数据(帐户密码),甚至可以支持用户上传文件(type 属性值为 file 时),如下所示:



    
    
        XssPayloadTest
    
    
        
        
        
        
             


使用不同类型的浏览器打开这个页面,观察它们是如何渲染,解释 type 属性的各种取值的:


HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX_第8张图片




HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX_第9张图片




HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX_第10张图片


关于通过 HTML 表单上传文件的实际应用,参考下面的例子:

一些论坛在发帖的时候,可以在帖子中插入附件或图片,这就是依赖于 HTML 表单的提交文件功能来实现上传的,以看雪论坛为例,在编辑帖子的富文本框顶部,有一列工具栏,点击其中笑脸右侧的“附件管理”按钮,就可以打开独立的浏览器窗口选择要上传的附件。这里我们使用 FireFox 的 Firebug 插件进行测试,在打开的浏览器窗口右上方点击瓢虫图标,从而对当前页面激活 Firebug:


wKiom1U4GAPDSKe1AAK86Nmxk8M697.jpg


在 Firebug 显示的管理附件页面的 HTML 源码中,依序展开 body 元素(节点)-> div 元素,即可看到 div 元素内部的 form 表单元素,使用 HTTP POST 方法提交,其 action 属性的值预设了负责处理表单提交的 URL 一部分,也就是 “newp_w_upload.php?do=manageattach&p=”,后面我们会使用 BurpSuite Proxy 的拦截 HTTP 请求功能验证,当用户点击右侧的“上传”按钮时,的确以 POST 方法请求这个 URL ,并且还会在请求体中携带一些其它的参数提交;

表单元素的 enctype 属性值 multipart/form-data (多部分表单数据),是表单能够上传文件的关键之一,它必须结合 POST 方法才能工作,因为处理用户输入文本数据的普通表单,在使用 POST 方法提交时,默认使用 application/x-www-form-urlencoded 对输入数据进行编码,也就是将数据组织成“字段名/字段值对”的形式,每个配对之间用 & 符号连接,当任一对字段中出现不可打印或特殊的 ASCII 字符,unicode 字符时,对其进行百分号 URL 编码,这就是 x-www-form-urlencoded 名称的由来。

编码后的数据被放在 HTTP 请求体中发送(作为对比,HTTP GET 方法将用户输入的数据放在请求头部第一行的 URL 后的查询字符串中发送)。

而处理用户上传文件的表单,则需要显式设置 enctype="multipart/form-data",用于告诉浏览器要处理的是文件(图片,视频等)。

后面会通过 BurpSuite Proxy 拦截到浏览器发出的“多部分表单数据”请求,详细介绍 multipart/form-data 这种数据提交编码格式


HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX_第11张图片


回到管理附件页面的 HTML 源码中,继续展开 form 元素,可以在其内部看到许多隐藏的 input 元素(input type="hidden"),浏览器不会在页面中显示属性为隐藏的 input 元素,但我们还是可以通过一些手段,例如这里的 Firebug 插件,查看和修改其内容,细心的你也许已经注意到了,这些隐藏的 input 元素的预设值,大部分与当前管理附件页面 URL 中的查询字符串中的值相同:


HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX_第12张图片


观察管理附件页面的结构,通过“浏览”按钮选择文件并上传,其顶部有一个字符串“从您的电脑上传文件”,将该字串复制到 Firebug 的搜索框中后回车,可以定位字串在 HTML 源码中的位置;从这个位置继续向下观察,我们找到了实现文件上传的“浏览”按钮的源码,也就是 6 个连续的 type 为 file 的 input 元素,前面已经介绍过当浏览器碰到 input type="file" 的时候,将显示一个按钮控件,让用户从本地硬盘中选择文件上传,这就是表单实现上传功能的第二个关键。


HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX_第13张图片


继续在页面源码中向下探索,找到一个 input 元素的 type 属性值为 submit;value 属性值为“上传”,这对应浏览器渲染的页面中的“上传”按钮。

注意其 onclick 属性的值为 return verify_upload(this.form);

这表明在按下该按钮时执行的函数为 verify_upload ,该函数定义在 body 元素内部,位于 div 元素的前面,大致的功能是检查并提示用户选择文件上传(如果用户没有选择文件就按下“上传”按钮):


HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX_第14张图片


HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX_第15张图片


接下来,使用 BurpSuite Proxy 拦截浏览器在处理通过 HTML 表单上传文件时,向服务器发送的 HTTP 请求,以及对方返回的 HTTP 响应,这样我们就可以深入理解 multipart/form-data (多部分表单数据)的内幕。

限于篇幅,关于 BurpSuite 的下载安装配置这里不作介绍,各位可以自行搜索相关教程。首先在看雪论坛的附件管理页面中,通过“浏览”按钮实际选择一个要上传的测试图片,加载目标图片后,还不要点击“上传”按钮,因为我们的重头戏就是使用 BurpSuite 拦截点击“上传”按钮时,浏览器发出的 HTTP 请求。

在保持上传页面窗口打开的状态下,通过点击 FireFox 的其它任意标签页或者独立窗口(或者原始的帖子编辑窗口)右上角的选项 -> 高级 -> “网络”选项卡,点击“连接”栏目右侧的“设置”按钮,选择“手动配置代理”单选框,配置 FireFox 使用监听在 127.0.0.1:8080 的 BurpSuite 代理访问互联网(BurpSuite 启动后默认监听在上述地址端口):


HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX_第16张图片


配置好浏览器使用代理后,启动 BurpSuite ,切换到 proxy 选项卡下的 Options 子选项卡,默认情况 BurpSuite 仅拦截客户端发出的 HTTP 请求,因此需要在

Intercept Server Responses 栏目中,勾选 “Intercept responses based on the following rules”方框,保持下面的拦截规则为默认状态即可,这样就能够拦截服务器端返回的 HTTP 响应了:


HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX_第17张图片


切换到 intercept 选项卡中,确保从左边开始数起,第三个按钮的状态为“intercept is on”,然后点击附件管理页面的“上传”按钮,此刻就能拦截到浏览器发起的 HTTP 请求,注意,这个请求还未到达服务器,如果点击左边第一个 “Forward”按钮,请求才会被转发至服务器,而在此之前,我们可以任意修改,编辑请求头部和主体的所有字段,内容,甚至第二个按钮“Drop”可以丢弃该请求,不转发给服务器;最后一个按钮“Action”提供了更多在***测试中实用的操作选项,各位可以自行测试。拦截到的 HTTP 表单上传文件请求数据包如下所示:


HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX_第18张图片


HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX_第19张图片



HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX_第20张图片


通过上面的介绍,各位对 HTML 表单上传文件的机制应该都了解清楚了,也可以尝试对其它站点的文件上传功能进行检测,顺便提一下,51cto 博客的文件上传不是基于 HTML 表单实现的,而是借助 Flash 浏览器插件的网络功能实现的,不过同样可以用 BurpSuite 拦截点击上传图片控件时,Flash 浏览器插件发起的 HTTP 请求或者通信流量,其原因在于,51cto 博客的服务器端返回的是基于 javascript 构建的文件上传界面的 HTML 文档,其中虽然没有用到表单元素,但是同样是使用 HTTP POST 方法提交数据,而且其 Content-type 请求头的值也是 multipart/form-data,由此产生的流量可以被 BurpSuite 拦截。各位可以自行测试研究,然后对比两者间的异同


HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX_第21张图片


HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX_第22张图片



HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX_第23张图片


总结:51cto 博客使用 POST 上传图片或者文件时,在请求体中的数据类型为 multipart/formdata,携带了实际表示图片文件的字节序列;服务器返回的响应体中的数据类型为 JSON ,包含一些通知客户端上传成功的轻量级信息(图片存储的 URL,名称等),浏览器的 javascript 解释引擎能够识别 JSON 数据并更新页面特定区域的数据或状态(例如在上传图片的界面右下方显示一个绿色的勾,就是用来响应 JSON 数据中的 "state":"SUCESS" 参数名/值对),在使用 AJAX 时,多数情况下 XMLHttpRequest 对象中也能保存由服务器返回的 JSON 数据。



3。 关于执行页面中 script 标签内代码和构建 DOM树的优先顺序

考虑下面的代码:



    
    
        XssPayloadTest
    
    
        
        div内的HTML是a节点
    


在第8行的 script 标签内部,取得 ID 为 a 的元素节点(即 div 元素)内部的 HTML 代码,然后在弹出的提示框中显示。而实际上,用三大浏览器测试,都不会弹出显示 div 元素内部 HTML 代码的提示框,原因在于,碰到 script 标签时,浏览器们直接调用 javascript 解释引擎执行其中的脚本代码,而此时 DOM 树中的节点还未构建完整:div 元素是在浏览器碰到第9行代码时,才添加到 DOM 树中的,而第8行的代码不等待文档的 DOM 树构建完成,就先读取还未创建的 ID 为 a 的 div元素,这会导致浏览器提示“无法读取null(不存在)元素的innerHTML属性”:


HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX_第24张图片

HTML元素属性测试总结,包含DOM,CSS,javascript 与 AJAX_第25张图片

其解决办法之一,将要操纵页面 DOM 节点的脚本代码放在最后,这样一来,在浏览器碰到 script 标签之前,所有的 DOM 节点都已经构建完毕:




    
    
        XssPayloadTest
    
        
        div内的HTML是a节点