web-dev-qa-db-ja.com

文字列がJSONかどうかをテストする方法は?

単純なAJAX呼び出しがあり、サーバーは有用なデータを含むJSON文字列またはPHP関数mysql_error()によって生成されたエラーメッセージ文字列を返します。このデータがJSON文字列かエラーメッセージかをテストするにはどうすればよいですか。

関数isJSONを使用して何かが配列かどうかをテストできるように、instanceofという関数を使用するとよいでしょう。

これは私が欲しいものです:

if (isJSON(data)){
    //do some data stuff
}else{
    //report the error
    alert(data);
}
120

JSON.parseを使用する

function isJson(str) {
    try {
        JSON.parse(str);
    } catch (e) {
        return false;
    }
    return true;
}
245
Bourne

このコードはJSON.parse(1234)またはJSON.parse(0)またはJSON.parse(false)またはJSON.parse(null) allはtrueを返します。

function isJson(str) {
    try {
        JSON.parse(str);
    } catch (e) {
        return false;
    }
    return true;
}

そこで、次のようにコードを書き直しました。

function isJson(item) {
    item = typeof item !== "string"
        ? JSON.stringify(item)
        : item;

    try {
        item = JSON.parse(item);
    } catch (e) {
        return false;
    }

    if (typeof item === "object" && item !== null) {
        return true;
    }

    return false;
}

テスト結果:

isJsonテスト結果

47
kubosho_

サーバーがJSONで応答する場合は、application/json content-typeになります。プレーンテキストメッセージで応答する場合は、text/plain content-typeになります。サーバーが正しいコンテンツタイプで応答していることを確認し、テストします。

21
Quentin

jQuery $.ajax()を使用する場合、応答がJSONの場合、応答にはresponseJSONプロパティが含まれます。これは次のように確認できます。

if (xhr.hasOwnProperty('responseJSON')) {}
11
rémy

これを要約しましょう(2019+の場合)。

引数truefalsenullなどの値は有効なJSON(?)

FACT:はい、いいえ!これらのプリミティブ値はJSON-parsableですが、整形式JSON構造ではありませんs。 JSONspecification は、JSONが名前/値のペアのコレクション(オブジェクト)または順序付けられた値のリスト(配列)の2つの構造に基づいていることを示します。

Argument:例外処理を使用して予期されることを実行しないでください。
(これは25以上の賛成票があるコメントです!)

FACT:いいえ!特にこのようなケースでは、try/catchを使用することは間違いなく合法です。それ以外の場合、トークン化/正規表現操作など、多くの文字列分析を行う必要があります。これはひどいパフォーマンスになります。

hasJsonStructure()

これは、データ/テキストに適切なJSON交換形式があるかどうかを確認することが目的の場合に役立ちます。

function hasJsonStructure(str) {
    if (typeof str !== 'string') return false;
    try {
        const result = JSON.parse(str);
        return Object.prototype.toString.call(result) === '[object Object]' 
            || Array.isArray(result);
    } catch (err) {
        return false;
    }
}

使用法:

hasJsonStructure('true')             // —» false
hasJsonStructure('{"x":true}')       // —» true
hasJsonStructure('[1, false, null]') // —» true

safeJsonParse()

また、一部のデータをJavaScript値に解析するときに注意が必要な場合に便利です。

function safeJsonParse(str) {
    try {
        return [null, JSON.parse(str)];
    } catch (err) {
        return [err];
    }
}

使用法:

const [err, result] = safeJsonParse('[Invalid JSON}');
if (err) {
    console.log('Failed to parse JSON: ' + err.message);
} else {
    console.log(result);
}
10

私はベストアンサーが好きですが、空の文字列の場合はtrueを返します。だからここに修正があります:

function isJSON(MyTestStr){
    try {
        var MyJSON = JSON.stringify(MyTestStr);
        var json = JSON.parse(MyJSON);
        if(typeof(MyTestStr) == 'string')
            if(MyTestStr.length == 0)
                return false;
    }
    catch(e){
        return false;
    }
    return true;
}
6

まあ...それはあなたがあなたのデータを受け取る方法に依存します。サーバーはJSON形式の文字列で応答していると思います(たとえば、PHPでjson_encode()を使用)。 JQueryポストを使用して、応答データをJSON形式に設定し、それが不正なJSONである場合、エラーが生成されます。

$.ajax({
  type: 'POST',
  url: 'test2.php',
  data: "data",
  success: function (response){

        //Supposing x is a JSON property...
        alert(response.x);

  },
  dataType: 'json',
  //Invalid JSON
  error: function (){ alert("error!"); }
});

ただし、タイプ応答をテキストとして使用している場合は、$。parseJSONを使用する必要があります。 jqueryサイトによると、「不正な形式のJSON文字列を渡すと、例外がスローされる可能性があります」。したがって、コードは次のようになります。

$.ajax({
  type: 'POST',
  url: 'test2.php',
  data: "data",
  success: function (response){

        try {
            parsedData = JSON.parse(response);
        } catch (e) {
            // is not a valid JSON string
        }

  },
  dataType: 'text',
});
5

たとえば、返されたJSONが常に{}で囲まれていることがわかっている場合は、実行できるテストがあります。その後、これらの文字または他のハッキングメソッドをテストできます。または、 json.org JSライブラリを使用して解析して、成功するかどうかをテストできます。

ただし、別のアプローチをお勧めします。 PHPスクリプトは、呼び出しが成功した場合はJSONを返しますが、そうでない場合は何かを返します。なぜalwaysJSONを返さないのですか?

例えば。

成功した呼び出し:

{ "status": "success", "data": [ <your data here> ] }

誤った呼び出し:

{ "status": "error", "error": "Database not found" }

これにより、クライアント側のJSの記述がはるかに簡単になります。必要なのは、「ステータス」メンバーとそれに応じた動作を確認するだけです。

4
mdm
var parsedData;

try {
    parsedData = JSON.parse(data)
} catch (e) {
    // is not a valid JSON string
}

ただし、http呼び出し/サービスは常に同じ形式のデータを返す必要があることをお勧めします。したがって、エラーが発生した場合は、このエラーをラップするJSONオブジェクトが必要です。

{"error" : { "code" : 123, "message" : "Foo not supported" } } 

そして、おそらくHTTPステータスと同様に5xxコードを使用します。

4
ZER0

私はそれを行うために2行だけを使用します

var isValidJSON = true;
try { JSON.parse(jsonString) } catch { isValidJSON = false }

それで全部です!

ただし、次の2つのトラップがあることに注意してください。
1。 JSON.parse(null)nullを返します
2。 JSON.parse()メソッドを使用して、任意の数値または文字列を解析できます。
JSON.parse("5")5を返します
JSON.parse(5)5を返します

コードを少し試してみましょう。

// TEST 1
var data = '{ "a": 1 }'

// Avoiding 'null' trap! Null is confirmed as JSON.
var isValidJSON = data ? true : false
try { JSON.parse(data) } catch(e) { isValidJSON = false }

console.log("data isValidJSON: ", isValidJSON);
console.log("data isJSONArray: ", isValidJSON && JSON.parse(data).length ? true : false);

Console outputs:
data isValidJSON:  true
data isJSONArray:  false


// TEST 2
var data2 = '[{ "b": 2 }]'

var isValidJSON = data ? true : false
try { JSON.parse(data2) } catch(e) { isValidJSON = false }

console.log("data2 isValidJSON: ", isValidJSON);
console.log("data2 isJSONArray: ", isValidJSON && JSON.parse(data2).length ? true : false);

Console outputs:
data2 isValidJSON:  true
data2 isJSONArray:  true


// TEST 3
var data3 = '[{ 2 }]'

var isValidJSON = data ? true : false
try { JSON.parse(data3) } catch(e) { isValidJSON = false }

console.log("data3 isValidJSON: ", isValidJSON);
console.log("data3 isJSONArray: ", isValidJSON && JSON.parse(data3).length ? true : false);

Console outputs:
data3 isValidJSON:  false
data3 isJSONArray:  false


// TEST 4
var data4 = '2'

var isValidJSON = data ? true : false
try { JSON.parse(data4) } catch(e) { isValidJSON = false }

console.log("data4 isValidJSON: ", isValidJSON);
console.log("data4 isJSONArray: ", isValidJSON && JSON.parse(data4).length ? true : false);


Console outputs:
data4 isValidJSON:  true
data4 isJSONArray:  false


// TEST 5
var data5 = ''

var isValidJSON = data ? true : false
try { JSON.parse(data5) } catch(e) { isValidJSON = false }

console.log("data5 isValidJSON: ", isValidJSON);
console.log("data5 isJSONArray: ", isValidJSON && JSON.parse(data5).length ? true : false);


Console outputs:
data5 isValidJSON:  false
data5 isJSONArray:  false

// TEST 6
var data6; // undefined

var isValidJSON = data ? true : false
try { JSON.parse(data6) } catch(e) { isValidJSON = false }

console.log("data6 isValidJSON: ", isValidJSON);
console.log("data6 isJSONArray: ", isValidJSON && JSON.parse(data6).length ? true : false);

Console outputs:
data6 isValidJSON:  false
data6 isJSONArray:  false
2
efkan

デコードして exception (nativeまたは json2.js )をキャッチしてみてください:

try {
  newObj = JSON.parse(myJsonString);
} catch (e) {
  console.log('Not JSON');
}

ただし、応答を常に有効なJSONにすることをお勧めします。 MySQLクエリからエラーが返された場合は、エラーと共にJSONを返送するだけです。

{"error":"The MySQL error string."}

その後:

if (myParsedJSON.error) {
  console.log('An error occurred: ' + myParsedJSON.error);
}
2
James Sumners

すべてのjson文字列は「{」または「[」で始まり、対応する「}」または「]」で終わるので、それを確認してください。

Angular.jsの仕組みは次のとおりです。

var JSON_START = /^\[|^\{(?!\{)/;
var JSON_ENDS = {
  '[': /]$/,
  '{': /}$/
};

function isJsonLike(str) {
    var jsonStart = str.match(JSON_START);
    return jsonStart && JSON_ENDS[jsonStart[0]].test(str);
}

https://github.com/angular/angular.js/blob/v1.6.x/src/ng/http.js

0
carlin.scott

TypeScriptモード:で提案します

export function stringify(data: any): string {
    try {
         return JSON.stringify(data)
    } catch (e) {
         return 'NOT_STRINGIFIABLE!'
    }
}
0
Mahyar SEPEHR