Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > Сложная ситуация с PHP + Ajax


Автор: Selestin 21.10.2010, 00:07
Добрый вечер!
Необходим совет.

Ситуация довольно тривиальная для php программиста, я думаю каждый сталкивался с этим, но как решить эту задачу - я пока не понимаю.

Суть:
Существует некий Ajax скрипт, который отсылает запрос php скрипту, php скрипт в свою очередь генерирует javascript код, который по вызову onreadystatechange выполняется с помощью функции eval().
На этом Ajax запрос заканчивает свою работу.

Возникло 2 вопроса:
1) Первый и самый важный.
Допустим существует некая строка:
Код
"A"B'C'D"E"

Ajax скрипт отсылает строку PHP скрипту с помощью POST запроса.

Преобразования выполняемые перед отправкой:
Заменим символы переноса строки на <br>, дабы записать данные в базу корректно, без лишних спец. символов, при этом сохранив смысл.
Код

    send_city = city_name.value.replace(/\\n|\\r\\n|\\r/g,"<br>");

Обеспечим корректную кодировку запроса.
Код
encodeURI(send_city)


PHP скрипт:
Загрузим POST переменную, ограничив длину в 50 символов, и сразу сконвертировав в нужную нам кодировку:
Код

$city_name  = iconv("UTF-8", "windows-1251", substr($_POST['city_name'],0,50));

Запишем данные в базу, предварительно проэкранировав спецсимволы:
Код

$city_name = mysql_real_escape_string($city_name);

Строка сейчас имеет вид:
Код
\"A\"B\'C\'D\"E\"


На этом работа PHP скрипта закончена, оповестим наш ajax, что данные записаны корректно, сгенерировав код выходного дива для дебага.
Код

exit("
alert(\"<div class='point' id='point$array[id]' onclick=\"point_clicked($array[id],$array[city_name]);\"></div>\");
");

Вот тут то и начинается самая веселуха, дело в том, что отпечатав строку, хтмл выглядит так:
Код

<div class='point' id='point$array[id]' onclick="point_clicked(2,\"A\"B\'C\'D\"E\");"></div>

Образуется код вида:
Код

onclick="point_clicked(2,\"

HTML считает, что код онклика корректен до первой заэкранированной кавычки и вываливается в ошибку синтаксиса.

Решения которые я вижу:
1) Добавить в строку str_replace("\\\"","&quot;",$str), тогда кавычки заменятся на хтмл код, однако я не считаю это лучшим решением.
2) Добавить на выходе что-то типа htmlspecialchars(), Однако в этом случае строка будет выглядеть вот так:
Код

onclick=\"point_clicked(2,\&quot;A\&quot;B\'C\'D\&quot;E\&quot;);

Лишние палки оставшиеся от экранирования мне не нужны.

Вопрос: Как корректно обрабатывать данные из базы, ведь из базы данные всегда будут экранированы \", дабы собрать корректный js вызов функции?
Как вообще обычно решаются такие задачи?

Второй вопрос:
Как известно выполнение Ajax скрипта ловят с помощью функции onreadystatechange, однако написав ajax функцию мы заранее задаем поведение скрипта, например вот так:
Код

    LINK_xmlhttp.onreadystatechange = function() {
        if (LINK_xmlhttp.readyState == 4) 
        {
            refresh_form();
            eval(LINK_xmlhttp.responseText);
        }
    }

Какой способ обычно используют, чтобы после успешно отработанного аякс запроса, выполнить нужную функцию. Ведь вызвать функцию, имеющую динамические аргументы, которые я получаю из аякс запроса, будет нельзя, т.к. в Ajax функции невозможно получить доступ к внешним переменным+это не безопасно, вдруг их значение измениться, а передавать сотни параметров в хидер AJAX запроса - не лучший вариант, ведь функций может быть много. Пока решаю эту проблему только Eval(), хороший ли это вариант?
Пример функции:
Код

function    ajax_request(method, url)    {
    var LINK_xmlhttp = false;

    try { LINK_xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); }
    catch (e) { try { LINK_xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
    catch (e) { try { LINK_xmlhttp = new XMLHttpRequest(); }
    catch (e) { LINK_xmlhttp = false; }}}
    if (!LINK_xmlhttp) return null;

    LINK_xmlhttp.open("POST", url, true);

    if(method=="POST")
    {
        LINK_xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        LINK_xmlhttp.setRequestHeader("Content-length", url.length);
        LINK_xmlhttp.setRequestHeader("Connection", "close");
    }

    LINK_xmlhttp.onreadystatechange = function() {
        if (LINK_xmlhttp.readyState == 4) 
        {
            refresh_form();
            eval(LINK_xmlhttp.responseText);
        }
    }
    LINK_xmlhttp.send(url);
    return;
}


Спасибо.

Автор: Selestin 21.10.2010, 11:52
1) Решено с помощью отката экранирования функцией stripslashes()
2) Актуально.

Автор: skyboy 21.10.2010, 11:59
Цитата(Selestin @  20.10.2010,  23:07 Найти цитируемый пост)
HTML считает, что код онклика корректен до первой заэкранированной кавычки и вываливается в ошибку синтаксиса.

может, все же проблема в другом?
код
Код

eval(alert("1\\\"2\\\"3\\\'4"))

успешно выводит 
Цитата

1"2"3'4

по меньшей мере в firefox. может, все ж проблема в javascript части?
ты просто делаешь eval(responseText)? или как?

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