1 (изменено: JSmаn, 2011-11-03 09:12:24)

Тема: JS: Эмуляция браузера

Объект Browser

Имеет всего четыре метода:
1. Navigate (GetOrPost, URL, Param, Callback)
       GetOrPost — обязательный параметр — принимает значения get или post
       URL — обязательный параметр — интернет-ресурс
       Param — обязательный параметр при post запросах
       Callback — необязательный параметр — ссылка на функцию, которая будет вызвана сразу же после ответа сервера (и до редиректа). Функция будет вызвана с тремя параметрами status, ResponseHeaders, Response.
2. SubmitForm (FormNameOrIndex, Values, Callback) — ввести данные в форму и отправить
       FormNameOrIndex — имя формы либо ее порядковый номер (с нуля).
       Value — обязательный параметр — объект со с заданными свойствами по заполнению формы: {param1:value1, param2:value2}
3. ParseDocument() возвращает объект document.
4. ClearCookies() - очистка кукисов.

Свойства:
1.     Redirect (true по умолчанию) - флаг поддержки редиректа.
2.    Response  - ответ сервера
3.    ResponseHeaders  - заголовки в ответе сервера.
4.    UserAgent (по умолчанию 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1')
5.    RefererString — URL реферера
6.     Location — текущий URL
7.     Cookie — флаг поддержки кукисов. (true по умолчанию)

Код:

var CreateObject = function (ProgId) { return WScript.CreateObject(ProgId)};

function Log(e)
{
//	  WScript.Echo(e);
return e;
}

function Browser()
{
	this.XMLHTTP = CreateObject("Msxml2.ServerXMLHTTP.6.0");
	this.Redirect = true;
	this.Response = null;
	this.Referer = true;
	this.RefererString = null;
	this.ResponseHeaders = null;
	this.Location = null;
	this.__CookieStorage = " ";
	this.UserAgent = 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1';
	this.__Document = CreateObject("HTMLFile");
	this.Cookie = true;
}

Browser.prototype = 
{
	__ParseCookie : function (m, cookie)
	{
		if (!this.__CookieStorage) this.__CookieStorage =" ";
		this.__CookieStorage+=" "+cookie+";";
		Log("Cookie Storage:\t"+this.__CookieStorage);
	},
	
	ClearCookies : function ()
	{
		this.__CookieStorage=" ";
	},

	Navigate : function (GetOrPost, URL, Param, Callback, RefererStr)
	{
		this.RefererString = RefererStr || this.Location;
	
		if (URL.indexOf("://")!=-1) this.Location=URL; else
		{
			if (!this.Location) return;
			this.Location = this.Location.match(/(^\w+:\/\/[\w\.]+)\//)[1]+URL;
		}
		
		URL = this.Location;
		
		if (/:\/\//.test(URL)) 
	
		Log("Navigate\t"+URL);
	
		Callback = Callback || function (){}; 
		!Param? Param = null : "";
		GetOrPost = GetOrPost.toUpperCase();
		
		this.XMLHTTP.open(GetOrPost, URL, false);
		this.XMLHTTP.setRequestHeader ('User-agent', this.UserAgent);
		this.XMLHTTP.setRequestHeader ("Content-Type", "application/x-www-form-urlencoded"); 
		this.XMLHTTP.setRequestHeader ("Accept", "text/html"); 
		if (this.Referer && this.RefererString)
			this.XMLHTTP.setRequestHeader ("HTTP_REFERER", this.RefererString); //this.RefererString
		
		if (GetOrPost=="POST") 
		{
			this.XMLHTTP.setRequestHeader ('Content-length', (!Param?"":Param).length);
			this.XMLHTTP.setRequestHeader ('Connection', 'close');
		}

		if (this.Cookie && this.__CookieStorage!=" ")
		{
			this.XMLHTTP.setRequestHeader ("Cookie", this.__CookieStorage);
		}

		this.XMLHTTP.send(GetOrPost=="POST"? Param : null);
				
		this.ResponseHeaders = this.XMLHTTP.getAllResponseHeaders();
		this.Response = this.XMLHTTP.responseText;

		if (this.Cookie)
		{
			this.ResponseHeaders.replace(/^Set-Cookie *: *([^;]+)/igm, function( obj ){ return function (m, cookie){ obj.__ParseCookie(m, cookie) } }(this));
		}

		Log(["Response status:\t"+this.XMLHTTP.status, "\n\nResponseHeaders:\n\n"+this.ResponseHeaders, "\n\nResponse:\n\n"+this.Response]);
		Callback(this.XMLHTTP.status, this.ResponseHeaders, this.Response);
		
		if (this.Redirect)
		{
			var s="";
			if (this.ResponseHeaders && /^Location: */im.test(this.ResponseHeaders))
			{
				s=this.ResponseHeaders.match(/^Location: *([^\n\r]+)/im)[1].toString();
				Log("Redirect to\t"+s);
				this.Navigate("GET", s, null, Callback);
			}
		}
	}, 
	
	ParseDocument : function ()
	{
		var Code = (this.Response || "").replace(/<script([^>]*)/, "<script type=\"text/plain\"");
		this.__Document.open();
		this.__Document.write(Code);
		this.__Document.close();
		return this.__Document;
	}, 
	
	SubmitForm : function (FormNameOrIndex, Values, Callback) // Values {param1:value1, param2:value2}
	{
		var DOM = this.ParseDocument();
		if (DOM.forms.length>0) 
		{
			var Form = DOM.forms[FormNameOrIndex];
			var InputElements = Form.getElementsByTagName('input');
			var Result=[];
			for (var i=0, l=InputElements.length; i<l; i++)
			if (InputElements[i].name && InputElements[i].name!="")
			Result.push(''+InputElements[i].name+'='+ InputElements[i].value);
			
			Result=Result.join("&");
			for (i in Values)
			{
				var re = new RegExp('(^|&)'+i+"=[^&]*","i")
				Result= Result.replace(re, '$1'+encodeURIComponent(i)+"="+encodeURIComponent(Values[i]));
				
				if (!re.test(Result)) Result+="&"+encodeURIComponent(i)+"="+encodeURIComponent(Values[i]);
			}
			
			Log("Serialized Form Data:\t"+Result);
			this.Navigate(Form.method, Form.action, Result, Callback);
		}		
	}
}

Использование:



function callback(a,b,c)
{
	WScript.Echo([a, b, c]);
}

var WB = new Browser();

	WB.Navigate("GET", "http://m.mail.ru/cgi-bin/login?noclear=1&page=folders");
	WB.SubmitForm(0, {"Login":"***","Domain":"mail.ru", "Password":"***"});

//	WB.Navigate("GET", "http://mail.ru/");
//	WB.SubmitForm(1, {"Login":"***","Domain":"mail.ru", "Password":"***"});


//	WB.Navigate("GET", "http://vk.com/", null, callback);
//	WB.SubmitForm(0, {email:"***@mail.ru", pass:"***"}, callback);
//	WB.Navigate("GET", "http://vk.com/", null, callback);

	WScript.Echo(WB.ParseDocument().body.innerText);