2015-12-10 4 views
2

Я хочу отправить XMLHttpRequest объект JSON в Perl Script (* .cgi) Но я не могу декодировать объект JSON в файле cgi.Ajax Communication: Malformed JSON string в Perl

Я всегда reveive сообщение об ошибке:

искаженной строки JSON, ни массива, объект, число, строка или атом, в символьное смещение 0 (до " (конца строки) ")

Это мой Javascript код:

//ajax communication for receiver/transceiver 
function doAjaxRequest(query) 
{ 
    if(whatReq == "") 
    { 
     alert('ERROR: Request-Type undefined'); 
     return; 
    } 

    if (window.XMLHttpRequest) 
    { 
     arequest = new top.XMLHttpRequest(); // Mozilla, Safari, Opera 
    } 
    else if (window.ActiveXObject) 
    { 
     try 
     { 
      arequest = new ActiveXObject('Msxml2.XMLHTTP'); // IE 5 
     } 
     catch (e) 
     { 
      try 
      { 
       arequest = new ActiveXObject('Microsoft.XMLHTTP'); // IE 6 
      } 
      catch (e) 
      { 
       alert('ERROR: Request not possible'); 
       return; 
      } 
     } 
    } 

    if (!arequest) 
    { 
     alert("Kann keine XMLHTTP-Instanz erzeugen"); 
     return false; 
    } 
    else 
    { 
     var url = "****.cgi"; 

     var dp = document.location.pathname; 

     arequest.open('post', url, true); 
     arequest.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); 

     //receiver function 
     arequest.onreadystatechange = function() 
             {  
              switch (arequest.readyState) 
              { 
               case 4: 

                if (arequest.status != 200) 
                { 
                 alert("Der Request wurde abgeschlossen, ist aber nicht OK\nFehler:"+arequest.status); 
                } 
                else 
                { 
                 var content = arequest.responseText; 
                 analyseResponse(content); 
                }   
               break; 

               default: 
                 //alert("DEFAULT:" + arequest.readyState); 
               break; 
              } 
             } 
     //transceiver function 
     query="jsonObj=" + JSON.stringify({name:"John Rambo", time:"2pm"}); 
     alert(query); 
     arequest.send(query) 
    } 
} 

А вот CGI файл:

#!/usr/bin/perl 

use CGI qw/:standard/; 
use CGI::Carp qw(fatalsToBrowser); 
use strict; 
use warnings; 
use JSON; 
use Data::Dumper; 

my $jsonObj = param('jsonObj'); 
my $json = JSON->new->utf8; 
my $input = $json->decode($jsonObj ); 

print Dumper(\$input); 

Можете ли вы мне помочь? Я не знаю, как получить доступ к объекту JSON.

спасибо.

+0

Нам нужно увидеть строку JSON. Попробуйте распечатать его. Но при угадывании - потому что вы тянете его как параметр, он кодируется URI. Сначала вам придется декодировать это. – Sobrique

+0

Вам не понадобится 'isquest.send (" jsonObj = "+ query)'? –

+0

я делаю предупреждение перед запуском запроса: JSON \t \t имя \t «Джон Рэмбо» \t время \t «2 вечера» – Ulf

ответ

1

В этом сообщении говорится, что у вас есть строка, отличная от JSON, в $jsonObj. Одним из наиболее распространенных случаев является пустая строка. Попробуйте распечатать исходный контент $jsonObj и убедитесь, что вы правильно настроили для работы CGI::param, а также проверяете встроенные в браузер инструменты, которые фактически отправляют данные.

Также я настоятельно рекомендую вам отбросить 10-летнее дерьмо ActiveX. Вы используете JSON.stringify, и все браузеры, которые его поддерживают, также поддерживают родной XMLHttpRequest.

1

я собирался голосовать, чтобы поставить вопрос на удержание из-за insufficient information to reproduce and diagnose the problem, но потом я понял, что ваш вопрос делает содержит достаточно улик, чтобы выяснить, что случилось — они просто очень хорошо спрятаны.

  • Clue # 1: Ваше сообщение об ошибке говорит (акцент мой):

    уродливы JSON строка, ни массив, объект, число, строка или атом, по характеру смещения 0 (до "(конец строки)")

Это означает, что переменная $jsonObj имеет длину 0, то есть она пуста.

Итак, что заставляет его быть пустым? Ну, код Perl выглядит как совершенно стандартный материал CGI, поэтому проблема должна быть либо в вашем JS-коде, либо в том, что вы не показывали нам (например, в конфигурации вашего веб-сервера). Поскольку мы не можем отлаживать то, что мы не можем видеть, давайте сосредоточимся на вашем JS-коде, где мы находим ...

  • Clue # 2: Там что-то не так с этой линии:

    arequest.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); 
    

Конечно, вы можете установить any content type you want для запроса POST, но CGI.pm ожидает получать контент в одном из стандартных форматов для отправки HTML-форм, то есть either application/x-www-form-urlencoded or multipart/form-data. Когда он получает что-то, помеченное как application/json, он не знает, как его разобрать, и так не будет. Таким образом, метод param() в вашем скрипте Perl ничего не вернет, поскольку, насколько это известно, клиент не отправил никаких параметров, которые он мог бы понять.

должен был предупреждением об этом где-то в ваших журналах ошибок веб-сервера, но вы, по-видимому, не думали их проверять. (Подсказка: вы действительно должны!)

(Вы могли бы также использовать the warningsToBrowser option of CGI::Carp, чтобы получить эти предупреждения, отправленные как HTML-комментарии, но я думаю, вы не знали об этом варианте. Также, чтобы сделать эту работу надежно , вы действительно должны use CGI :: Carp перед тем модуль CGI, так что он может поймать любые ранние ошибки)

во всяком случае, исправление проста:. просто заменить application/json в коде JS с application/x-www-form-urlencoded, так как это то, что вы на самом деле пытаетесь отправить на сервер. Вы также должны убедиться, что ваши данные в формате JSON на самом деле является правильно URL-закодирован перед вложением его в запросе, путем пропускания выходного JSON.stringify() через encodeURIComponent(), как это:

var data = {name:"John Rambo", time:"2pm"}; 
var query = "jsonObj=" + encodeURIComponent(JSON.stringify(data)); 

(я также второй Oleg Предложение В. Волкова избавиться от всех устаревших вещей ActiveX в вашем JS-коде. Фактически, вы могли бы сделать еще лучше, используя современную библиотеку JS-утилиты, например, jQuery, которая обеспечивает удобные функции-обертки, чтобы вы не даже нужно напрямую связываться с XMLHttpRequest.)