Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей.
Здесь обсуждаются безопасность, программирование, технологии и многое другое.
Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
 |
JavaScript - полезные трюки и решения |

29.01.2007, 19:42
|
|
Banned
Регистрация: 01.08.2006
Сообщений: 725
Провел на форуме: 7681825
Репутация:
4451
|
|
JavaScript - полезные трюки и решения
Начнем
Потребовалось точно узнать что за браузер использует пользователь . Тк способ с HTTP_USER_AGENT не является стопроцентным надо было найти другое решение. После ковыряния интернета в поисках нужной информации , наткнулся на соответсвующий док от mozilla dev team http://www.mozilla.org/docs/web-developer/sniffer/browser_type.html , но к сожалению они наивно верят что браузер можно точно определить используя navigator.userAgent; , поэтому я прибег к другому выходу - нашел различия в обработке js и результат перед вами - скрипт точно обрабатывает движки на Gecko ( Firefox,Netscape,Mozilla) , Оперу и ИЕ.
PHP код:
function out(value) { document.getElementById("result").innerHTML = document.getElementById("result").innerHTML + value; }
function testBrowser() { productVersion = ""; out("Suggested browser : "+window.navigator.userAgent+"<br/>"); if ( document.defaultCharset != '' && document.defaultCharset != undefined && document.characterSet == undefined && document.body) { productVersion=window.navigator.userAgent.substr(window.navigator.userAgent.indexOf("MSIE")+5,3); out("Detected browser : Internet Explorer <br/>Browser version in User-Agent is: "+ parseFloat(productVersion)); } if (window.opera && document.defaultCharset == undefined && document.characterSet != "" && document.characterSet != undefined && self.innerHeight) { productVersion=window.navigator.userAgent.substr(window.navigator.userAgent.indexOf("Opera")+6,4); out("Detected browser : Opera <br/>Browser version in User-Agent is: "+ parseFloat(productVersion)); } if (document.defaultCharset == undefined && !window.opera && document.characterSet != "" && (self.innerHeight)) { productVersion=window.navigator.userAgent.substr(window.navigator.userAgent.indexOf("Gecko")+6,8)+ ' ('+ window.navigator.userAgent.substr(8,3) + ')'; out("Detected browser : Mozilla <br/>Browser version in User-Agent is: "+ parseFloat(productVersion)); } if (productVersion == "") { out("Failed to fingerprint browser name , but i suggest it is "+window.navigator.userAgent); } }
Пример страницы _http://underwater.xtoolz.ru/test.html
|
|
|
Способы решения проблем с кодировкой в Ajax |

04.12.2007, 00:39
|
|
Познающий
Регистрация: 22.02.2006
Сообщений: 67
Провел на форуме: 4155100
Репутация:
2033
|
|
Способы решения проблем с кодировкой в Ajax
[= Суть проблемы =]
Ответ сервера при использовании Ajax по умолчанию приходит в кодировке "utf-8".
Если запрашиваемая страница изначально имеет кодировку "windows-1251", то кириллические символы будут безвозвратно искажены свойством responseText. В таком случае вывод ответа сервера будет представлен знаками вопроса "?", или другими неопознанными символами.
[= Способ решения =] Их много. Все способы можно разделить на две группы: изменение кодировки на стороне сервера и на стороне клиента.
Когда мы имеем доступ к серверу, особых проблем обычно не возникает: хедеры, встроенные функции, перекодировка по таблицам символов. Описаний этого полно в нете.
Обратная ситуация. Например, нашли мы уязвимость XSS, желаем использовать Ajax для незаметного получения каких-либо данных с других страниц на сервере. При этом: во-первых, кодировка у страниц "windows-1251", во-вторых, сервер в ответе на Ajax-запрос не указывает кодировку пересылаемых данных.
В таких случаях возникает необходимость изменить кодировку уже на стороне клиента.
Универсального способа для этого нет. Для каждого браузера (группы браузеров) они свои. Эти способы, являясь от части продуктом моего обобщения разрозненной информации, а отчасти моего собственного творчества, я представляю.
[= Вариант, работающий во всех основных браузерах =]
test.html (необходимо убирать пробелы-разрывы, которые вставляет сайт)
PHP код:
<html>
<div id=qwerty></div>
<script>
if (window.execScript)
window.execScript('Function BinaryToString(Binary) \r cl1=1 \r cl2=1 \r cl3=1 \r L=LenB(Binary) \r Do While cl1<=L pl3=pl3&Chr(AscB(MidB(Binary,cl1,1))) \r cl1=cl1+1 \r cl3=cl3+1 \r If cl3>300 Then \r pl2=pl2&pl3 \r pl3="" \r cl3=1 \r cl2=cl2+1 \r If cl2>200 Then \r pl1=pl1&pl2 \r pl2="" \r cl2=1 \r End If \r End If \r Loop \r BinaryToString=pl1&pl2&pl3 \r End Function', 'VBScript');
var request=false;
try {request=new XMLHttpRequest();}
catch (forIE) {request=new ActiveXObject('Msxml2.XMLHTTP');}
function ReadFile()
{
request.open("GET", 'text.html');
if (request.overrideMimeType)
{
request.overrideMimeType('text/html; charset=windows-1251');
request.onreadystatechange=override;
}
else
request.onreadystatechange=readResponse;
request.send(null);
}
function override()
{
if (request.readyState == 4)
{
request.open("GET", 'text.html');
request.onreadystatechange=readResponse;
request.send(null);
}
}
function readResponse()
{
if (request.readyState == 4)
{
if (request.overrideMimeType)
document.getElementById('qwerty').innerHTML=request.responseText;
else
document.getElementById('qwerty').innerHTML=BinaryToString(request.responseBody);
}
}
</script>
<input type=button value='Жмах' onclick='ReadFile()'>
</html>
text.html
Код:
<html>Здесь что-нибудь на русском</html>
А теперь по каждому браузеру в отдельности, чтобы стало понятно тем, кто не разобрался.
1) Internet Explorer
Объекты Msxml2.XMLHTTP и XMLHttpRequest (IE 7.0) в этом браузере имеют фирменное свойство - "responseBody". В нем находится ответ сервера не в обычном строчном, а в бинарном виде. То есть в том виде, когда еще он не распарсился в соответствии с какой-либо кодировкой. В данном случае именно эта сторона для наc имеет значение. Будем парсить бинарный ответ самостоятельно.
В стандартном JavaScript функций для работы с таким бинарным ответом сервера нет. IE имеет несколько элементов управления ActieX, которые могут это делать, но в некоторых случаях они из соображений безопасности бывают выключены.
Имеется отличный способ обработки такого ответа с помощью VBScript, в котором присутствуют необходимые для этого встроенные функции.
VBScript-функция
Код:
<script language=vbscript>
Function BinaryToString(Binary)
'Antonin Foller, http://www.pstruh.cz
'Optimized version of a simple BinaryToString algorithm.
Dim cl1, cl2, cl3, pl1, pl2, pl3, L
cl1 = 1
cl2 = 1
cl3 = 1
L = LenB(Binary)
Do While cl1<=L
pl3 = pl3 & Chr(AscB(MidB(Binary,cl1,1)))
'Аналогов функций AscB() и MidB() в js нет.
cl1 = cl1 + 1
cl3 = cl3 + 1
If cl3 > 300 Then
pl2 = pl2 & pl3
pl3 = ""
cl3 = 1
cl2 = cl2 + 1
If cl2 > 200 Then
pl1 = pl1 & pl2
pl2 = ""
cl2 = 1
End If
End If
Loop
BinaryToString = pl1 & pl2 & pl3
End Function
</script>
Внедряем vbs-функцию в js с помощью фирменной функции IE - execScript()
(убрать пробел в предпоследнем упоминании функции BinaryToString)
PHP код:
<html>
<div id=qwerty></div>
<script>
window.execScript('Function BinaryToString(Binary) \r cl1=1 \r cl2=1 \r cl3=1 \r L=LenB(Binary) \r Do While cl1<=L pl3=pl3&Chr(AscB(MidB(Binary,cl1,1))) \r cl1=cl1+1 \r cl3=cl3+1 \r If cl3>300 Then \r pl2=pl2&pl3 \r pl3="" \r cl3=1 \r cl2=cl2+1 \r If cl2>200 Then \r pl1=pl1&pl2 \r pl2="" \r cl2=1 \r End If \r End If \r Loop \r BinaryToString=pl1&pl2&pl3 \r End Function', 'VBScript');
var request = new ActiveXObject('Msxml2.XMLHTTP');
function ReadFile()
{
request.open('GET', 'text.html');
request.onreadystatechange=readResponse;
request.send(null);
}
function readResponse()
{
if (request.readyState == 4) document.getElementById('qwerty').innerHTML=BinaryToString(request.responseBody); // передаем в функцию BinaryToString бинарный ответ сервера в качестве параметра и помещаем в див результат ее работы
}
</script>
<input type=button value='Жмах' onclick='ReadFile()'>
</html>
2) FireFox, Netscape
Используется метод overrideMimeType() объекта реквест
PHP код:
<html>
<div id=qwerty></div>
<script>
var request = new XMLHttpRequest();
function ReadFile()
{
request.open("GET", 'text.html');
request.overrideMimeType('text/html; charset=windows-1251'); // метод переопределяет заголовок "Content-Type" от сервера
request.onreadystatechange=readResponse;
request.send(null);
}
function readResponse()
{
if (request.readyState == 4)
document.getElementById('qwerty').innerHTML=request.responseText; }
</script>
<input type=button value='Жмах' onclick='ReadFile()'>
</html>
3) Opera
Метод overrideMimeType() предусмотрен в этом браузере в объекте реквест, однако в текущей версии 9.24 кодировку он не переопределяет.
У данного браузера имеется другая особенность. Состоит она в автоматическом определении кодировки контента. То есть, когда запрашиваешь аяксом страницу в 'windows-1251' первый раз (с хоста), она выводится искаженной. Во второй раз та же страница отображается уже корректно. Данную особенность мы и будем использовать.
PHP код:
<html>
<div id=qwerty></div>
<script>
var request = new XMLHttpRequest();
function ReadFile()
{
request.open("GET", 'text.html'); // первый запрос
request.onreadystatechange=override;
request.send(null);
}
function override()
{
if (request.readyState == 4)
{
request.open("GET", 'text.html'); // второй запрос
request.onreadystatechange=readResponse;
request.send(null);
}
}
function readResponse()
{
if (request.readyState == 4) // во второй раз, поскольку мы не разорвали соединение, состояние готовности сразу равно 4, в свойство попадает ответ сервера, находящийся в памяти.
document.getElementById('qwerty').innerHTML=request.responseText;
}
</script>
<input type=button value='Жмах' onclick='ReadFile()'>
</html>
В действительности не происходит ожидания ответа сервера при втором запросе, результат выводится сразу. Потеря времени ничтожна мала.
Автоматическое определение кодировки Оперой производится независимо от установленной пользователем (пользовательской кодировкой может не быть "win-1251"), а также от настроек кэширования.
Ключи поиска: кодировка Ajax кодировка перекодировка Ajax перекодировка UTF-8 Win-1251
Последний раз редактировалось LeverOne; 26.12.2007 в 21:51..
|
|
|
Распознавание браузера на стороне клиента |

06.01.2008, 15:39
|
|
Познающий
Регистрация: 22.02.2006
Сообщений: 67
Провел на форуме: 4155100
Репутация:
2033
|
|
Распознавание браузера на стороне клиента
[= Вводные замечания =]
1. Скрипт предназначен для распознавания браузера юзера самим браузером юзера, минуя navigator.userAgent. Аналогов ему нет.
2. Нижепредставленный скрипт отличается от скрипта распознавания gemaglabin'a в первом сообщении тем, что:
А) распознает не только группу браузеров, основанных на движке Gecko (Firefox, Netscape Navigator, Mozilla), но и сами эти браузеры внутри группы;
Б) распознает конкретные версии браузеров или диапазоны версий, внутри которых наборы объектов, свойств и методов реализованной модели javascript характеризуются определенным постоянством.
В) Мда, и код у него больше.
3. В качестве признаков идентификации были взяты две особенности:
Первая: само наличие или отсутствие объектов, свойств и методов в модели javascript браузера, набор которых изменяется от версии к версии.
Вторая: возможность вывода этих объектов, свойств и методов в цикле for ... in. Даже имеющиеся объекты-методы не всегда доступны к просмотру в цикле for ... in. Этот показатель также переменен от версии к версии.
4. Разумеется, в строгом смысле скрипт нельзя назвать скриптом на javascript. В нем использованы как средства Jscript, так и фирменные возможности других браузеров, не предусмотренные стандартами javascript.
[= Скрипт =]
PHP код:
var result=''; // сюда будем записывать результат идентификации
if(window.opera)
{
result+='Opera '; // уже точно Opera
var d=new Array();
for (e in document) d.push(e);
d=d.toString();
if (window.XSLTProcessor) // 9.0-9.25
{
if (d.indexOf('execCommand')==-1) result+='9.24';
else
{
if (document.selectNodes)
{
if (d.indexOf('postMessage')==-1) result+='9.25';
else result+='9.02-9.23';
}
else
{
if (d.indexOf('onload')!=-1) result+='9.01';
else result+='9.0';
}
}
}
else
if (document.all) // 8.0-8.54
{
if (!opera.SRPNumber) result+='8.50-8.54';
else
{
if (document.postMessage) result+='8.01-8.02';
else result+='Opera 8.0';
}
}
else // 7.02-7.54
{
if (window.navigate) result+='7.50-7.54';
else
{
if (window.getComputedStyle) result+='7.20-7.23';
else
{
if (window.VXMLAudioRecording) result+='7.11';
else result+='7.02-7.1';
}
}
}
}
else if (document.layers) result+='Netscape Navigator 4.x'; // Old Netscape
else if (document.defaultCharset == undefined && !window.opera) // Gecko based
{
var a=new Array();
for (b in document.body) a.push(b);
a=a.toString();
var h=new Array();
for (i in document) h.push(i);
h=h.toString();
if (document.defaultView.globalStorage)
{
if (document.defaultView.getInterface) result+='Firefox 2.0-2.0.0.11';
else result+='Netscape Navigator 9.0-9.0.0.5';
}
else
{
if (document.defaultView.getInterface && window.Components) result+='Firefox 1.5-1.5.0.8';
else
{
if (a.indexOf('addEventListener')==-1)
{
if (h.indexOf('preferredStylesheetSet')!=-1) result+='Firefox 1.0.6-1.0.7';
else result+='Mozilla 1.7.10-1.7.13';
}
else
{
if (document.defaultView.setTransparency) result+='Netscape Navigator 8.1';
else
{
if (window.pkcs11.addmodule && window.OPEN_NEW_WIN_ONLY) result+='Netscape Navigator 8.0.2-8.0.4';
else
{
if (document.actualEncoding)
{
if (h.indexOf('preferredStylesheetSet')!=-1) result+='Firefox 1.0-1.0.4';
else result+='Firefox 0.8-0.9 or Mozilla 1.7-1.7.8 or Netscape Navigator 7.2';
}
else
if (sidebar.CHECK_ANONYMOUS) result+='Netscape Navigator 7.0-7.02';
}
}
}
}
}
}
else // IE
{
var JScript='';
/*@cc_on @*/
/*@ JScript=@_jscript_version @*/
JScript==3.0? result+='Internet Explorer 4.0': JScript==5.0? result+='Internet Explorer 5.0': JScript==5.5? result+='Internet Explorer 5.5': JScript==5.6? result+='Internet Explorer 6.0': JScript==5.7? result+='Internet Explorer 7.0': result+='Browser unknown';
}
document.write('<b><font size=4>Result of fingerprinting:</font></b> '+result+'<br /><b><font size=4>Browserinfo (navigator.userAgent):</font></b> '+window.navigator.userAgent);
//\\ LeverOne //\\
[= Заключительные замечания =]
1. О недостатках
А) Распознавание основано на предположении, что клиент использует один из тех браузеров, на которые нацелено распознавание: FireFox, Mozilla, Netscape Navigator, Opera, Internet Explorer. Остальные могут быть распознаны некорректно, хотя многое сделано, чтобы такие браузеры были обозначены отдельно как "неопознанные".
Б) Брались во внимание только финальные версии, но не альфа, бета и т.д.
В) Просмотр исходного кода страницы до распознавания может повлечь ошибку идентификации. Необходимо просматривать его после получения результата.
Г) Из-за того, что объекты-методы могут то появляться, то исчезать в новых версиях (ибо процесс расширения возможностей нелинеен во времени) скрипт может давать ошибочные результаты при распознавании более новых версий, чем заложено в нем самом. Например, Opera 9.25 ближе к 9.23, чем к 9.24.
Д) Тестировалось всё под Виндовс, как те же самые браузеры поведут в других OC, утверждать не могу.
2. Версии распознающихся браузеров:
IE: 4.0, 5.0, 5.5, 6.0, 7.0
Opera: 7.02, 7.03, 7.10, 7.11, 7.20, 7.21, 7.22, 7.23, 7.50, 7.51, 7.52, 7.53, 7.54, 8.0, 8.01, 8.02, 8.50, 8.51, 8.52, 8.53, 8.54, 9.0, 9.01, 9.02, 9.10, 9.20-9.25
_http://arc.opera.com/pub/opera/win
Firefox: 0.8, 0.9, 1.0, 1.0.1-1.0.7, 1.5, 1.5.0.1-1.5.0.8, 2.0, 2.0.0.1-2.0.0.11
Netscape Navigator: 4.x, 7.0, 7.01, 7.02, 7.2, 8.02, 8.03, 8.04, 8.1, 9.0, 9.0.0.1-9.0.0.5
_http://browser.netscape.com/downloads/archive
Mozilla: 1.7, 1.7.1-1.7.13
_http://www.mozilla.org/releases/
Последний раз редактировалось LeverOne; 12.01.2008 в 23:44..
|
|
|

06.01.2008, 19:19
|
|
Moderator - Level 7
Регистрация: 24.02.2006
Сообщений: 447
Провел на форуме: 2872049
Репутация:
705
|
|
Ответ сервера при использовании Ajax по умолчанию приходит в кодировке "utf-8".
Если запрашиваемая страница изначально имеет кодировку "windows-1251", то кириллические символы будут безвозвратно искажены свойством responseText. В таком случае вывод ответа сервера будет представлен знаками вопроса "?", или другими неопознанными символами.
Кодировка утф предназначена для англоязычных стран восновном. Не понимаю зачем нужно посылать инфу в одной кодировке а получать в другой?
PHP код:
$objAjax = new xajax(); // компонент класса xajax
$objAjax->setCharEncoding("windows-1251"); // выставляем кодировку
Что делать если отключен js и другие компоненты у пользователя все проверки пойдут лесом? И еще как можно точно определить поисковых ботов на js.
|
|
|

08.01.2008, 05:18
|
|
Флудер
Регистрация: 20.11.2006
Сообщений: 3,316
Провел на форуме: 16641028
Репутация:
2371
|
|
Зачем на js их определять?
Есть определенные диапазоны и юзер-агенты их...
|
|
|
|
 |
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|