Javascript 无法解析JSON?

Javascript 无法解析JSON?,javascript,json,firefox,Javascript,Json,Firefox,这是我的javascript文件 var callAjax = function(relative_path){ var Ajax = new XMLHttpRequest(); Ajax.onreadystatechange = function() { //Since what we are calling a local file. we cannot get a 200 OK Status.

这是我的javascript文件

var callAjax = function(relative_path){
        var Ajax =  new XMLHttpRequest();
            Ajax.onreadystatechange = function() {

                //Since what we are calling a local file. we cannot get a 200 OK Status.
                //So We check only the readystate
                if(Ajax.readyState==4){
                    serialized = Ajax.responseText;
                    alert(serialized); 
                    // ^^ alerts fine.
                    return serialized;
                }

            }

            Ajax.open("GET",relative_path, true);
            Ajax.send();    
};


var readSettings = function(){
    var data = callAjax('settings.json');
    obj  = JSON.parse(data);
    alert(obj);
}
现在,当我调用html中的某个地方的
readSettings()
时,第一个警报(在callAjax函数中)会正确地提醒JSON。但第二个警报不会。当我看到控制台时,错误是:

[21:04:02.233]语法错误:JSON.parse:意外字符@file:///home/cipher/Codes/looma-f5/js/looma.js:23

My settings.json是:

{

    "classes": 8,
    "config": "classConfig",
    "locale": {
        "en": "localeEn"
    },
    "defaultLocale": "en"
}

我通过在线工具运行了JSON,看起来不错。为什么firefox不解析这些呢?

问题是你可以
JSON。在
callAjax
返回后立即解析
。在执行
onreadystate
回调之前。由于操作的异步性质,你应该从回调中触发解析

问题是,您可以在
callAjax
返回后立即解析
JSON。在执行
onreadystate
回调之前。由于操作的异步性质,您应该从回调触发解析。

您没有从
callAjax
函数返回任何值。您需要将在
onreadystatchange
处理程序中使用结果的ur代码

您确实有一个
return
语句,但它在回调内部,返回回调的内部调用方,并在
callAjax
返回后调用

因为
callAjax
似乎是相当通用的,所以一个好的方法是让该函数接受回调作为参数,然后调用它,传递响应

//                  receive a callback----vv
var callAjax = function(relative_path, callback){
        var Ajax =  new XMLHttpRequest();

        Ajax.onreadystatechange = function() {
            if(Ajax.readyState==4){
                serialized = Ajax.responseText;
                alert(serialized); 

                // vv---invoke the callback
                callback(serialized);
            }
        }
        Ajax.open("GET",relative_path, true);
        Ajax.send(); 
};

var readSettings = function(){
    // pass a callback ----------------------vv
    var data = callAjax('settings.json', function(data) {
        var obj  = JSON.parse(data);
        alert(obj);
    });
}

如果
readSettings
的调用者需要处理响应,那么您可以让
readSettings
也接收一个回调,然后直接将其传递,或者将其包装到另一个函数中,以便它可以首先进行解析

我将给出一个假设它需要包装的示例

// receive a callback----------vv
var readSettings = function(callback){
    // pass a callback that wraps the first---vv
    var data = callAjax('settings.json', function(data) {
        // parse the response data
        var obj  = JSON.parse(data);

        // invoke the callback, passing it the parsed object
        callback(obj);
    });
}


您没有从
callAjax
函数返回任何值。您需要将使用结果的代码放入
onreadystatchange
处理程序中

您确实有一个
return
语句,但它在回调内部,返回回调的内部调用方,并在
callAjax
返回后调用

因为
callAjax
似乎是相当通用的,所以一个好的方法是让该函数接受回调作为参数,然后调用它,传递响应

//                  receive a callback----vv
var callAjax = function(relative_path, callback){
        var Ajax =  new XMLHttpRequest();

        Ajax.onreadystatechange = function() {
            if(Ajax.readyState==4){
                serialized = Ajax.responseText;
                alert(serialized); 

                // vv---invoke the callback
                callback(serialized);
            }
        }
        Ajax.open("GET",relative_path, true);
        Ajax.send(); 
};

var readSettings = function(){
    // pass a callback ----------------------vv
    var data = callAjax('settings.json', function(data) {
        var obj  = JSON.parse(data);
        alert(obj);
    });
}

如果
readSettings
的调用者需要处理响应,那么您可以让
readSettings
也接收一个回调,然后直接将其传递,或者将其包装到另一个函数中,以便它可以首先进行解析

我将给出一个假设它需要包装的示例

// receive a callback----------vv
var readSettings = function(callback){
    // pass a callback that wraps the first---vv
    var data = callAjax('settings.json', function(data) {
        // parse the response data
        var obj  = JSON.parse(data);

        // invoke the callback, passing it the parsed object
        callback(obj);
    });
}

AJAX中的“A”表示异步。提交XMLHttpRequest后,
callAjax
函数将立即返回,而无需等待请求完成。因此,
JSON.parse
将被调用,返回值为
callAjax
(这不是您正在寻找的JSON),并生成错误

一段时间后,XMLHttpRequest将完成,并且
onreadystatechange
回调将运行。您可以从此函数返回JSON,但JSON不会返回任何位置,因为它是从回调返回的,而不是从
callAjax
返回的

作为事件的结果,您必须执行JSON解析和后续活动在AJAX中是异步的。提交XMLHttpRequest后,
callAjax
函数将立即返回,而无需等待请求完成。因此,
JSON.parse
将被调用,返回值为
callAjax
(这不是您要查找的JSON),并生成错误

一段时间后,XMLHttpRequest将完成,并且
onreadystatechange
回调将运行。您可以从此函数返回JSON,但JSON不会返回任何位置,因为它是从回调返回的,而不是从
callAjax
返回的


由于
onreadystatechange
事件,您必须执行JSON解析和后续活动。

您的JSON是utf-8格式的吗?我发现这不是错误的真正原因:)。不管怎样,谢谢@sumurai8您的json是utf-8格式的吗?我发现这不是错误的真正原因:)。无论如何,谢谢@sumurai8,将代码放入回调处理程序是一个好的开始,我不建议将来将所有代码都嵌套在回调处理程序中;)(只是旁注)。@MichaelKrelin黑客:谢谢:)该死!我愚蠢的错误。我尝试使用回调(事实上:使用了相同的变量:),但问题是我无法通过readSettings返回
obj
?任何解决办法@MichaelKrelin黑客@BlueSkies@cipher:是的,这是同样的问题。调用
readSettings
的任何内容都可以传入回调,回调可以传递到
callAjax
。如果需要,它可以在另一个先进行解析的函数中传递。我将用一个例子来更新。是的,您还需要确保在填充对象之后进行所有后续操作。只需从同一个回调中触发它们即可。虽然将代码放入回调处理程序是一个良好的开端,但我不建议将所有未来的代码嵌套在回调处理程序中;)(只是旁注)。@MichaelKrelin黑客:谢谢:)该死!我愚蠢的错误。我尝试使用回调(事实上:使用了相同的变量:),但问题是我无法通过readSettings返回
obj
?任何解决办法@MichaelKrelin黑客@BlueSkies@cipher:是的,这是同样的问题。调用
readSettings
的任何内容都可以传入回调,回调可以传递到
callAjax
。如果需要,它可以在另一个先进行解析的函数中传递。我会更新一个例子。是的,你还需要确保