Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Базы Данных > PHP+AJAX+mysql - проблема с кодировкой


Автор: flashaa 29.6.2007, 01:00
Может быть вы подскажете, почему при получении запроса от стороннего скрипта (AJAX)  и вставке его ответа как innerHTML в браузерах опера и ИЕ кодировки ответа оказываются разные, но обе неверные.  При чем такая ошибка только при работе с аяксом. Если открыть скрипт отдельно, он показывает вменяемую информацию в обоих браузерах.

Скрипт берет информацию из БД 

Автор: sTa1kEr 29.6.2007, 01:17
flashaa, вообще-то при использовании AJAX лучше использовать кодироку utf-8. Т.е. перед работой с БД выполняете запрос "SET NAMES 'utf8'" и прописваете в XML <?xml version="1.0" encoding="UTF-8" standalone="yes"?>

Автор: flashaa 29.6.2007, 01:48
А можете более подробно?
Т.е. и перед сохранением и перед извлечением данных из бд делать запрос "SET NAMES 'utf8'" ?
А <?xml version="1.0" encoding="UTF-8" standalone="yes"?> -  это надо прописать в тело страницы, которая будет получать запросы через AJAX ?

Автор: flashaa 29.6.2007, 02:48
Я понял вас, сделал так, но теперь почемуто правильно видны только данные из ОПЕРЫ - при чем правильно в обоих браузерах видны. А данные из ИЕ в обоих браузерах - белиберда.

Значит так: 
при выводе через xml и переводе скриптовых данных в utf-8 правильно отображаются сторонние данные(которые не были приняты через АЯКС). в других случаях эти данные неправильны во всех браузерах.
значит надо оставить utf как кодировку вывода скрипта.

Теперь: данные, принятые через аякс отображаются в браузерах по разному!  при приеме они проходят перекодировку из utf-8 в windows-1251 . О чем это может говорить?

Автор: flashaa 29.6.2007, 15:13
Значит работает скрипт чата, который состоит из страницы с JS-кодом, изначально генерируемой через PHP и ещё одного PHP-скрипта, который выводит новые данные.

В качестве GET-параметра php- скрипту передается номер чатовой комнаты при обновлении,
а так же AJAX передает скрипту данные от пользователя для добавления в БД. (JS-код в самом конце поста)
запрашиваемый скрипт выводит (echo) все внутреннее представление чата.
Кодировка самой страницы windows-1251.

Теперь сама проблема: скрипт работает нормально при первой загрузке (без AJAX).
Но когда подключаю AJAX вот тут и начинаются проблемы с кодировкой. Это просто тупик. Просмотрел 
множество решений. 

Например,
1) принудительное задание кодировки в выводе,
2) использование xml
 
Код

Header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); 
Header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
Header("Pragma: no-cache"); // HTTP/1.0
Header("Last-Modified: ".gmdate("D, d M Y H:i:s")."GMT");
//header("Content-Type: text/html; charset=windows-1251"); - на случай кодировки win-1251
//header('Content-Type: text/xml'); 
//echo '<?xml version="1.0" encoding="UTF-8" standalone="yes">'; - на случай Utf-8
//echo '<response>';   - для XML


3)перекодирование при сохранении в базу
Код

$q_update_chat="insert into posts (`text`,`author`,`game`,`time`)
values ('".
iconv("utf-8","windows-1251",trim(htmlspecialchars($_GET["text"],ENT_QUOTES)))."',".$_SESSION["user_id"].
",".$_GET["id"].",'".strftime("%Y-%m-%d %H:%M:%S")."')";


4)перекодирование при извлечении из базы
Код

echo "<img src='country/".mysql_result($r_0,0,"country").".gif'>
<a href='profile.php?act=user&id=".mysql_result($r_0,0,"id")."'>"
.iconv("windows-1251","utf-8",mysql_result($r_0,0,"login"))."</a>:
".iconv("utf-8","windows-1251",mysql_result($r_chat,$i,"text"))."<br>";





В итоге получается взаимоисключающий результат: либо  корректно отображается в Опере, либо в ИЕ, либо изначально правильно либо после обновления через AJAX.. В итоге не получается чтобы ВСЕ было правильно всегда и везде.
Читал про то, что AJAX нормально работает если сама страница которая обновляется будет в кодировке utf-8, но для меня это невозможно. Помогите...


Яваскрипт в обновляемой странице:

Код



<script language="javascript">
/* Создание нового объекта XMLHttpRequest для общения с Web-сервером */
var xmlHttp = false;
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
try {
  xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
  try {
    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
  } catch (e2) {
    xmlHttp = false;
  }
}
@end @*/

if (!xmlHttp && typeof XMLHttpRequest != "undefined") {
  xmlHttp = new XMLHttpRequest();
}
function go()
{
text=document.getElementById("text").value;
if (escape(text)=="") return;
var url = "http://'.$_SERVER["HTTP_HOST"].
'/show_chat.php?act=add&id='.mysql_result($r,0,"id").'&text="+urldecode(text);
  xmlHttp.open("GET", url, true);
  xmlHttp.onreadystatechange = updatesend;
  xmlHttp.send(null);
}

function callServer() {


   var url = "http://'.$_SERVER["HTTP_HOST"].'/show_chat.php?id='.mysql_result($r,0,"id").'";
    
  xmlHttp.open("GET", url, true);
  xmlHttp.onreadystatechange = updatePage;
  xmlHttp.send(null);
}
var x;
function updatesend() {
document.getElementById("upd").innerHTML="<b>Чат</b> ( отправка )"; 
document.getElementById("but").disabled=true; 
 x=setInterval(en,6000);
document.getElementById("text").value=""; 
  if (xmlHttp.readyState == 4) {
    var response = xmlHttp.responseText;
    document.getElementById("chat_div").innerHTML=response; 
    document.getElementById("upd").innerHTML="<b>Чат</b>";
    //alert(response);
         }
}
function updatePage() {
document.getElementById("upd").innerHTML="<b>Чат</b> ( обновление )"; 
  if (xmlHttp.readyState == 4) {
    var response = xmlHttp.responseText;
    document.getElementById("chat_div").innerHTML=response; 
    document.getElementById("upd").innerHTML="<b>Чат</b>";
  }
}
function k(a)
{
if (a!=13) go();
}
function en()
{
document.getElementById("but").disabled=false; 
clearInterval(x);
}
var y=setInterval(callServer,5000);

</script>


Автор: mishaSL 29.6.2007, 17:28
flashaa, если вы используете кодировку windows-1251 и нет возможности перейти на utf-8, то тогда кодировка windows-1251 должна быть везде:
1. поставьте заголовок header("Content-type: text/html; charset=windows-1251"); и в основном файле который выводит информацию и в файлах show_chat.php и т.д. которые грузятся через Ajax.
Плюс желательно добавите еще следующие заголовки в файлы подгружаемые через ajax:
Код

header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");


2. После соединения с БД выполните запрос : mysql_query("set names cp1251"); этот запрос поставьте после всех соедитений с БД (если их несколько)
3. в данном случае не надо использовать iconv и так все должно работать.

Автор: flashaa 29.6.2007, 17:35
mishaSL, спасибо, но указанный вами метод (обе страницы в windows-1251) я уже пробовал, результат в моем посте такой, что в этом случае абсолютно все данные( и сохраненные в бд через АЯКС и без него) искажаются в обоих браузерах.
Правда я не использовал запрос mysql_query("set names cp1251"), попробую с ним.

Автор: mishaSL 29.6.2007, 17:44
Цитата(flashaa @  29.6.2007,  17:35 Найти цитируемый пост)
Правда я не использовал запрос mysql_query("set names cp1251"), попробую с ним.

Попробуйте, точно должно работать. Проверено неоднократно.

Автор: flashaa 29.6.2007, 17:48
Спасибо большое! Решение действительно оказалось в этом запросе!

Автор: mishaSL 29.6.2007, 17:56
Всегда пожалуйста. smile 
Т.к. вы новичек на форуме, напоминаю: когда вопрос решен у первого поста в топике есть возможность пометить "вопрос решенным".

Автор: flashaa 30.6.2007, 06:37
Странно, но снова появилась проблема.
Теперь вот как: все сообщения, ОТПРАВЛЕННЫЕ В БАЗУ из Оперы видны неверно,  а сообщения из ИЕ - верно..

Код

 Членистоногий: Р»РґР»
 Членистоногий: p2
 Подмышка: ы
 Членистоногий: РЅСѓ РЅСѓ
 Подмышка: ывывы


Членистоногий пишет из Оперы, Подмышка из ИЕ.
В обоих браузерах выглядит вот так.

Строку mysql_query("set names cp1251") добавил в файл db_connect.php, который выполняет подключение и селекцию  БД, т.е. теперь после каждого подключения гарантировано идет этот разпрос...  smile 

Судя по результатам смены кодировки в опере, опера получает строку в Unicode smile  smile 

Автор: sTa1kEr 30.6.2007, 12:43
Цитата(flashaa @  30.6.2007,  06:37 Найти цитируемый пост)
Судя по результатам смены кодировки в опере, опера получает строку в Unicode    

Скорее всего Опера и FF через AJAX возвращает данные в UTF-8 вне зависимости от используемой кодировки. В данном случае лучше всего использовать mbstrings, т.к. UTF-8 от одно-байтовых кодировок он умеет отличать.
Код

$charset =mb_detect_encoding($GET["text"], "UTF-8, Windows-1251");
if ($charset == "UTF-8")
{
   $text = mb_convert_encoding($GET["text"], "Windows-1251", "UTF-8");
}

Или так
Код

mb_detect_order("UTF-8, Windows-1251");
$text = mb_convert_encoding($GET["text"], "Windows-1251");

Автор: flashaa 30.6.2007, 23:43
С использованием двух последних приемов теперь в обоих браузерах вместо любых букв - как русских, так и не русских - пустота. МОжет быть можно как-то переконвертировать в ява-скрипте? И может ли кто-нибудь бросить рабочий пример хтмл+аякс - пхп,  чтобы кодировка страницы была win-1251. Пока я видел пример только в UTF-8

Автор: flashaa 1.7.2007, 00:11
Заменил 
mysql_query("set names cp1251")  на mysql_query("set names utf8")

+ при запросе аякса добавил JS-фукнцию  encodeURIComponent() от передаваемого текста и теперь все отображается, так и знал, что надо ещё в js эту строку подготовить к отправке,ибо каждый браузер  ее по своему представляет  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)