forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   JavaScript / HTML (http://forum.boolean.name/forumdisplay.php?f=136)
-   -   Проблема с преобразованием типов Javascript (http://forum.boolean.name/showthread.php?t=17922)

St_AnGer 22.02.2013 11:19

Проблема с преобразованием типов Javascript
 
Доброго времени суток, Булчане!

Пилю тут сайт (использую php, mysql, jquery, ajax), и нужно через аякс-запрос принять ответ от сервера (сервер в зависимости от параметро запроса посылает в ответ командой echo определённую цифру (от 0 до 3, если быть совсем точным), ну т.е. echo "2"; и т.п.), и в зависимости от этой цифры вывести определённое сообщение в <div> с помощью innerHTML.

Вообщем суть проблемы - гугл хром отказывается преобазовывать принятый ответ в любые типы в ява-скрипте. Ответ принимается прекрасно и его можно вывести даже в любой элемент. Но его тип преобразовать невозможно в число, и как строка он тоже не обрабатывается. Я не пойму никак что это за тип такой.

В Опере (а я работаю только в ней и ни в чём больше, но сайт увы не для меня одного) меня всё пучком работает и преобразуется как надо (с помощью parseInt() вообще замечательно). Тот же parseInt() в хроме выдаёт NaN. Уже попробовал всё что нашёл в тырнете (преобразовывал даже в строку путём кода var st = new String(...), а потом в число), всё равно не пашет. toString() тоже не помогает. Даже банальное умножение этого дела на 1 (да и на любое число) в опере выдаёт правильный результат, а в хроме - NaN. ЧЯДНТ? Объясните глупому пожалуйста.

апд
забыл код, который некорректно работает (все варианты приводить не буду):

Код:

var resp = req.responseText;
alert(resp);

var response = new String(resp);
response = response*2;
alert(response);

Результат: первое сообщение цифра с сервера (правильная), второе сообщение - NaN.

Следующий код работает как надо в хроме:

Код:

var resp = 123; //если '123', то тоже работает правильно.
alert(resp);
var response = new String(resp);
response = response*2;
alert(response);

Результат: сообщение 123 и сообщение 246.
Значит проблема именно в типе принятого ответа. Или в браузере, хотя это уже врятли :)

Reizel 22.02.2013 13:33

Ответ: Проблема с преобразованием типов Javascript
 
Мэйби там где-нито лишний пробел, или какой нито мусор вначале\конце строки хром приаттачивает? В конце концов, можно тупо switch замутить, в лоб, если вариантов немного.

moka 22.02.2013 15:08

Ответ: Проблема с преобразованием типов Javascript
 
responseText - и так строка в любом случае.
Делать new String - не нужно.

Затем ты строку умножаешь на 2. Что ты ожидаешь получить умножив строку на 2?

Код:

var res = "2";
console.log(typeof(res));
console.log(res);

var number = parseInt(res);
console.log(typeof(number));
console.log(number);
console.log(number * 2);

Вот тут я беру строку с символом "2", вывожу сперва тип переменной затем саму переменную.
Далее преобразую в число, и вывожу тип переменной, саму переменную и затем умножение.

St_AnGer 22.02.2013 15:51

Ответ: Проблема с преобразованием типов Javascript
 
Цитата:

Сообщение от MoKa (Сообщение 253512)
responseText - и так строка в любом случае.
Делать new String - не нужно.

Затем ты строку умножаешь на 2. Что ты ожидаешь получить умножив строку на 2?

Код:

var res = "2";
console.log(typeof(res));
console.log(res);

var number = parseInt(res);
console.log(typeof(number));
console.log(number);
console.log(number * 2);

Вот тут я беру строку с символом "2", вывожу сперва тип переменной затем саму переменную.
Далее преобразую в число, и вывожу тип переменной, саму переменную и затем умножение.


Да не в том проблема. Если работать с переменными, которые я сам назначаю жёстко в скрипте - всё преобразуется. Проблема именно с принятым ответом от сервера. А умножал я просто так, что бы проверить. По идее же при умножении ведь перевод в число делается 100%.

А вот typeOf полезная функция, попробую, узнаю что такое там приходит. Спасибо.

moka 22.02.2013 16:20

Ответ: Проблема с преобразованием типов Javascript
 
Цитата:

Сообщение от St_AnGer (Сообщение 253515)
Да не в том проблема. Если работать с переменными, которые я сам назначаю жёстко в скрипте - всё преобразуется. Проблема именно с принятым ответом от сервера. А умножал я просто так, что бы проверить. По идее же при умножении ведь перевод в число делается 100%.

А вот typeOf полезная функция, попробую, узнаю что такое там приходит. Спасибо.

responseText - всегда будет строкой, в любом случае.
Ты где-то реально напортачил.

Если у тебя проблема с другим кодом, так почему ты его не выложишь?

St_AnGer 22.02.2013 19:00

Ответ: Проблема с преобразованием типов Javascript
 
проблема не с другим кодом, а именно в том месте что я выложил. Принятый от сервера ответ не преобразуется в число, чего я и хочу добиться. Да и проблемы бы я не заметил никогда, если бы с гугл хрома не попытался проверить. В Опере ведь всё идеально работает.

Сейчас попробовал через typeof узнать тип ответа - вполне себе уверенный string. Странно, не пойму почему тогда преобразование не происходит. И не может преобразовать именно принятый от сервера ответ, потому что если руками создать переменную типа string - всё преобразуется как надо.

Так, нашёл в чём проблема - хром (ну или его скриптовый движок точнее) приделывает 2 пробела в начале полученного ответа. Странно.

Дайте мне ответ на вопрос: как преобразовать ответ от сервера в число? Способы из гугла возвращают NaN, все.

Код:

var resp = parseInt(req.responseText);
                           
switch (resp)
{
case 0:
case 1:
case 2:
case 3:
}

преобразование нужно для определения действия. Если брать case "0", case "1" и т.д., то результата всё равно нет, условия не срабатывают.

St_AnGer 22.02.2013 19:37

Ответ: Проблема с преобразованием типов Javascript
 
Собственно говоря решил проблему.

Опытным путём узнав что хром добавляет лишние пробелы в сообщение - я просто их обрезал и дальше преобразовал в число через parseInt:
Код:

String.prototype.trim = function(str) { return str.replace(/^\s+|\s+$/g, ""); }                           
var resp = new String().trim(req.responseText);

switch (parseInt(resp))
{
...
}

Как то так. Может не красиво, но работает как часы. И в данном случае как раз подходит. Спасибо тем кто помогал и навёл на мысль!

moka 22.02.2013 21:14

Ответ: Проблема с преобразованием типов Javascript
 
Ну начну с того что возвращать просто число - никто так не делает.
Обычно возвращают JSON что в разы удобнее.

Во вторых переписывать стандартную функцию trim - я бы не делал этого вообще. Это ужасный говнокод, и если ты юзаешь где-то ещё trim'ы, а обычно народ юзает, то у тебя на trim'ы будет уходить в раз 10 больше ресурсов чем на стандартный.

Плюс писать так:
PHP код:

var resp = new String().trim(req.responseText); 

Это гиперговнокондство, т.к. ты уже имеешь прототип функцию для String'а.
Так что пиши так:
PHP код:

var resp req.responseText.trim(); 

Далее, да, ты никогда не должен полагаться на идентичность обработки ответов в броузерах на столь детальном уровне. Пустые пробелы или наличие /n или /r в конце сообщения. Также есть проблемы когда возвращается application/json, и в броузере стоит специальный аддон который json запросы красиво отображает - это дело вообще поломает твой запрос.
Если шлёшь от сервера данные, и хочешь чтобы они были максимально идентичны, шли с нужным Content-Type который не будет модифицироваться броузерами, например:
PHP код:

Content-Typetext/plain 

Такой запрос не должен быть обработан от сервера.

А вообще, я тебе порекомендую делать как все - шли JSON от сервера, так даже будет проще и удобнее слать сложные ответы.
PHP код:

header('Content-type: application/json');
$data = array();
$data['number'] = 4;
echo 
json_encode($data); 

И на клиенте так:
PHP код:

var data JSON.parse(req.responseText);
switch(
data.number) {
  ... 

Так ты сможешь слать любой приемлемой сложности данные, и без проблем парсить их в JSON.

St_AnGer 22.02.2013 23:04

Ответ: Проблема с преобразованием типов Javascript
 
Цитата:

Сообщение от MoKa (Сообщение 253544)
Ну начну с того что возвращать просто число - никто так не делает.
Обычно возвращают JSON что в разы удобнее.

Во вторых переписывать стандартную функцию trim - я бы не делал этого вообще. Это ужасный говнокод, и если ты юзаешь где-то ещё trim'ы, а обычно народ юзает, то у тебя на trim'ы будет уходить в раз 10 больше ресурсов чем на стандартный.

Плюс писать так:
PHP код:

var resp = new String().trim(req.responseText); 

Это гиперговнокондство, т.к. ты уже имеешь прототип функцию для String'а.
Так что пиши так:
PHP код:

var resp req.responseText.trim(); 

Далее, да, ты никогда не должен полагаться на идентичность обработки ответов в броузерах на столь детальном уровне. Пустые пробелы или наличие /n или /r в конце сообщения. Также есть проблемы когда возвращается application/json, и в броузере стоит специальный аддон который json запросы красиво отображает - это дело вообще поломает твой запрос.
Если шлёшь от сервера данные, и хочешь чтобы они были максимально идентичны, шли с нужным Content-Type который не будет модифицироваться броузерами, например:
PHP код:

Content-Typetext/plain 

Такой запрос не должен быть обработан от сервера.

А вообще, я тебе порекомендую делать как все - шли JSON от сервера, так даже будет проще и удобнее слать сложные ответы.
PHP код:

header('Content-type: application/json');
$data = array();
$data['number'] = 4;
echo 
json_encode($data); 

И на клиенте так:
PHP код:

var data JSON.parse(req.responseText);
switch(
data.number) {
  ... 

Так ты сможешь слать любой приемлемой сложности данные, и без проблем парсить их в JSON.



Спасибо большое! С JSON не работал ещё, но сейчас думаю пришла пора изучать данный вопрос.
А то что сейчас у меня есть - сделано для отмазки, лишь бы работало. Плохо, да, нельзя так делать.
Не отрррицаю (c) А.Р. Бородач :-)

Про стандартную функцию trim не знал, каюсь. Набил в гугле "javascript убрать пробелы" и воспользовался первым попавшимся результатом. Потом бы всё равно конечно исправил, но да, глупо с моей стороны.

Просто учусь делать активные сайты (пока что делаю копию сайта моего клана с юкоза).
Собственно это всё что я тут спрашивал у меня в форме входа используется (4 варианта ответа сервера возможных: 0-входим, 1-ненайден логин, 2-неверный пароль, 3-почему-то не удалось войти), и в зависимости от ответа нужное действие (например 0 отправляет на скрипт входа после некоторого времени). Пока что вот разбираюсь с входом и сессиями пользователей. Вопросов вагон и мааааленькая тележка, а время на из изучение, увы, отсутствует :( А ещё форум собрался писать сам. Жесть короче, губозакатыватель нужно купить :-)

moka 22.02.2013 23:09

Ответ: Проблема с преобразованием типов Javascript
 
Цитата:

Сообщение от St_AnGer (Сообщение 253550)

Спасибо большое! С JSON не работал ещё, но сейчас думаю пришла пора изучать данный вопрос.
А то что сейчас у меня есть - сделано для отмазки, лишь бы работало. Плохо, да, нельзя так делать.
Не отрррицаю (c) А.Р. Бородач :-)

Про стандартную функцию trim не знал, каюсь. Набил в гугле "javascript убрать пробелы" и воспользовался первым попавшимся результатом. Потом бы всё равно конечно исправил, но да, глупо с моей стороны.

Просто учусь делать активные сайты (пока что делаю копию сайта моего клана с юкоза).
Собственно это всё что я тут спрашивал у меня в форме входа используется (4 варианта ответа сервера возможных: 0-входим, 1-ненайден логин, 2-неверный пароль, 3-почему-то не удалось войти), и в зависимости от ответа нужное действие (например 0 отправляет на скрипт входа после некоторого времени). Пока что вот разбираюсь с входом и сессиями пользователей. Вопросов вагон и мааааленькая тележка, а время на из изучение, увы, отсутствует :( А ещё форум собрался писать сам. Жесть короче, губозакатыватель нужно купить :-)

Ну конечно, спрашивай тут, чем можем поможем.

Но вот запросы в гугл делать на русском - я настоятельно не рекомендую, т.к. 80% ответов есть на StackOverflow - а там по русски не болтают.

Также форум я бы свой не писал, это слишком гемор. Лучше возьми какой phpBB и поставь, настрой, и можешь его изменять.
Конечно писать свой форум - опыт, но думаю лучше писать что-то полезнее и опыт тоже будет. А для того чего есть уже решения - используй.

Phantom 23.02.2013 05:01

Ответ: Проблема с преобразованием типов Javascript
 
Я так и не понял, откуда у автора появлялись лишние пробелы при получении ответа от сервера? Это же бред.

St_AnGer 23.02.2013 13:34

Ответ: Проблема с преобразованием типов Javascript
 
Дак вот я тоже думаю что бред, но гугл хром успешно к ответу приделывает 2-3 пробела. Сам. Ничего не говоря. Просто вот так принимает ответ и всё. А в Опере я такой проблемы не наблюдал. Возможно, какая то особенность движка хрома, или ещё чего. не знаю вообщем. Я бы и не подумал что там чтото лишнее придеывается, если бы ответ не запихнул в alert("msg:"+req.responseText);. Должна была получиться слитная строка наподобие msg:1, в опере так и получилось, а в хроме получилось msg: 1.

Ну сейчас я через JSON сдеал, как Максим посоветовал. Работает точно на опере и на хроме правильно, всё передаётся и принимается верно.

moka 24.02.2013 16:08

Ответ: Проблема с преобразованием типов Javascript
 
А ещё такой момент, глянь свой php файл, и убедись что сразу на первой строке стоит <?php и затем нету ?> вообще в конце. Тогда может и не будет пробелов, но это хотя решает скорее проблему с пробелами на конце.
Но если <?php не на первой строке - то и на начале.
Но как ты уже заметил JSON с этим сам справляется.

St_AnGer 24.02.2013 20:14

Ответ: Проблема с преобразованием типов Javascript
 
Цитата:

Сообщение от MoKa (Сообщение 253668)
А ещё такой момент, глянь свой php файл, и убедись что сразу на первой строке стоит <?php и затем нету ?> вообще в конце...

Что то как то я не въехал, честно. Т.е. файл должен выглядеть так:
Код:

<?php
...
содержимое файла
...

?
Или я неправильно понял?

у меня файл выглядит следующим образом:
Код:

<?php
...
содержимое файла
...
?>


moka 24.02.2013 21:26

Ответ: Проблема с преобразованием типов Javascript
 
Цитата:

Сообщение от St_AnGer (Сообщение 253686)
Что то как то я не въехал, честно. Т.е. файл должен выглядеть так:
Код:

<?php
...
содержимое файла
...

?
Или я неправильно понял?

у меня файл выглядит следующим образом:
Код:

<?php
...
содержимое файла
...
?>


Верно, то что ты в первом варианте привел.
Если это полностью PHP файл, то закрывать тег не нужно - так избешишь пробелов и новой строки на конце строки.
Потому что /n обычно не выводиться, но он присутствует почти во всех ответах от сервера.
Следственно сравнение ответа с сервера с простой строкой порой выдаёт false, визуально они идентичны, но /n - не отображается при выводе или пробелы после строки, поэтому они разные.


Часовой пояс GMT +4, время: 12:11.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot