【问题标题】:Ajax Communication: Malformed JSON string in PerlAjax 通信:Perl 中格式错误的 JSON 字符串
【发布时间】:2016-03-16 05:18:57
【问题描述】:

我想通过 XMLHttpRequest 将 JSON 对象发送到 Perl 脚本 (*.cgi) 但是我无法解码 cgi 文件中的 JSON 对象。

我总是收到错误消息:

格式错误的 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 对象。

非常感谢。

【问题讨论】:

  • 我们需要查看 JSON 字符串。尝试打印它。但猜测一下 - 因为您将它作为参数拉取,所以它是 URI 编码的。您必须先对其进行解码。
  • 你不需要arequest.send("jsonObj="+query) 吗?
  • 我在开始查询之前发出警报:JSON 名称“John Rambo”时间“2pm”
  • 我的 $test = param('jsonObj');打印自卸车(\$test);结果->脚本中的格式错误的标头。错误头=$VAR1 = \undef;: accmanagertest.cgi
  • 您尚未从脚本中输出 HTTP 标头。既然你有 CGI::Carp,只需 die Dumper $testfatalsToBrowser 会为你处理它。当然,除非您明确期待 JSON 回复,在这种情况下,您必须检查您的服务器错误日志。当然,您也可以使用浏览器中的开发工具检查消息。 IE。在 Chrome 中,按 F12,转到网络,发送 AJAX 请求,单击列表中显示的内容并阅读。

标签: javascript json ajax perl


【解决方案1】:

此消息表明您在 $jsonObj 中有非 JSON 字符串。一种特别常见的情况是空字符串。尝试打印出 $jsonObj 的原始内容并确保您正确设置了所有内容以使 CGI::param 正常工作,并使用浏览器的内置工具检查它是否实际发送数据。

另外我强烈建议你扔掉 10 年前的 ActiveX 垃圾。您使用的是JSON.stringify,所有支持它的浏览器也支持原生XMLHttpRequest

【讨论】:

    【解决方案2】:

    由于insufficient information to reproduce and diagnose the problem,我正要投票搁置您的问题,但后来我意识到您的问题确实包含足够的线索来找出问题所在 - 他们真的很好隐藏。

    • 线索 #1:您的错误消息显示(强调我的):

      格式错误的 JSON 字符串,既不是数组、对象、数字、字符串也不是原子,在字符偏移量 0 处(在“(字符串结尾)”之前)

    这意味着您的 $jsonObj 变量的长度为 0,即它是空的。

    那么,是什么导致它为空?好吧,Perl 代码看起来就像是完全标准的 CGI 代码,所以问题一定出在您的 JS 代码中,或者出在您没有向我们展示过的东西上(例如您的 Web 服务器配置)。由于我们无法调试我们看不到的东西,让我们专注于您的 JS 代码,我们在哪里找到...

    • 线索#2:这行有问题:

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

    当然,您可以为 POST 请求设置 any content type you want,但 CGI.pm 期望以 HTML 表单提交的标准格式之一接收内容,即 either application/x-www-form-urlencoded or multipart/form-data。当它收到标记为 application/json 的东西时,它不知道如何解析它,因此也不知道。因此,Perl 脚本中的param() 方法不会返回任何内容,因为就它而言,客户端没有发送它可以理解的参数。

    应该在您的网络服务器错误日志中的某处对此有警告,但您大概没有想过要检查这些。 (提示:你真的应该这样做!)

    (您也可以使用the warningsToBrowser option of CGI::Carp 将这些警告作为 HTML cmets 发送,但我猜您也不知道该选项。此外,为了使该选项可靠地工作,您确实需要use CGI::Carp CGI 模块之前,以便它可以捕获任何早期错误。)

    无论如何,解决方法很简单:只需将 JS 代码中的 application/json 替换为 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 V. Volkov 的建议,即在您的 JS 代码中删除所有过时的 ActiveX 内容。事实上,您可以使用现代 JS 实用程序库(例如 jQuery)做得更好,它提供方便的包装函数,因此您甚至不必直接弄乱 XMLHttpRequest。)

    【讨论】:

      猜你喜欢
      • 2015-03-07
      • 1970-01-01
      • 2014-04-24
      • 1970-01-01
      • 2015-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-14
      相关资源
      最近更新 更多