จะทดสอบว่าสตริงนั้นเป็น JSON หรือไม่?


191

ฉันมีเรียกง่ายๆ AJAX, และเซิร์ฟเวอร์จะกลับทั้งสตริง JSON mysql_error()มีข้อมูลที่เป็นประโยชน์หรือสตริงข้อความข้อผิดพลาดที่ผลิตโดยฟังก์ชั่นของ ฉันจะทดสอบได้อย่างไรว่าข้อมูลนี้เป็นสตริง JSON หรือข้อความแสดงข้อผิดพลาด

มันเป็นการดีที่จะใช้ฟังก์ชั่นที่เรียกว่าisJSONเหมือนกับที่คุณสามารถใช้ฟังก์ชั่นinstanceofเพื่อทดสอบว่ามีบางสิ่งที่เป็นอาร์เรย์หรือไม่

นี่คือสิ่งที่ฉันต้องการ:

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

อาจจะใช้eval()ถ้ามันกลับundefinedมาแล้วมันไม่ใช่ JSON
MatuDuke

4
สิ่งนี้ได้รับการแก้ไขแล้วที่นี่: stackoverflow.com/questions/3710204/…
Reinard

2
ขอบคุณทุกคนขอโทษที่ฉันไม่พบโพสต์อื่นก่อนหน้านี้
jeffery_the_wind

1
ในทางเทคนิคแล้วนี่ไม่ใช่การล่อลวงของ 3710204 เพราะมันถามว่าเป็น json ที่ถูกต้องหรือไม่ซึ่งเป็นแถบที่สูงกว่าที่จะผ่านได้มากกว่านั้นคือ json เลย
carlin.scott

คำตอบ:


324

ใช้ JSON.parse

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

53
การจัดการข้อยกเว้นไม่ควรใช้เพื่อทำสิ่งที่คาดหวัง
luisZavaleta

46
JSON.parse(1234)หรือJSON.parse(0)หรือJSON.parse(false)หรือJSON.parse(null)ทั้งหมดจะไม่ยกข้อยกเว้นและจะคืนจริง !! อย่าใช้คำตอบนี้
Zalaboza

19
@Zalaboza 1234, 0, falseและnullทุกคนค่า JSON ที่ถูกต้อง ถ้าคุณต้องการเพรดิเคตที่ทดสอบว่า JSON แสดงวัตถุคุณจะต้องทำเพิ่มอีกเล็กน้อย
Michael Lang

20
JSON.parseทำการคำนวณจำนวนมากเพื่อวิเคราะห์สตริงและให้วัตถุ json แก่คุณหากสำเร็จ แต่คุณกำลังละทิ้งผลลัพธ์ที่ผู้ใช้บางคนอาจต้องการใช้ ที่ดูเหมือนจะไม่ดี ฉันต้องการแทนreturn {value: JSON.parse(str), valid: true};และในการป้องกันการจับreturn {value: str, valid: false};.. tryParse()และฉันต้องการเปลี่ยนชื่อฟังก์ชั่น
นาวาซ

7
@luisZavaleta ดังนั้นสิ่งที่คุณแนะนำเป็นวิธีการ
PirateApp

80

รหัสนี้JSON.parse(1234)หรือJSON.parse(0)หรือJSON.parse(false)หรือJSON.parse(null)ทั้งหมดจะกลับจริง

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 ผลการทดสอบ


4
เยี่ยมมาก! คำสั่งสุดท้ายของคุณหากสามารถทำให้เป็นคำสั่งส่งคืนอย่างง่ายเช่น:return (typeof suspect === "object" && suspect !== null);
Nebulosar

39

มาปะยางนี้กัน (สำหรับปี 2019+)

อาร์กิวเมนต์ : ค่าเช่นtrue, false, nullที่ถูกต้อง JSON (?)

ข้อเท็จจริง : ค่าดั้งเดิมเหล่านี้สามารถแยกวิเคราะห์JSON ได้แต่ไม่มีโครงสร้าง JSON ที่มีรูปแบบที่ดี ข้อมูลจำเพาะJSON ระบุว่า JSON ถูกสร้างขึ้นบนสองโครงสร้าง: ชุดของคู่ชื่อ / ค่า (วัตถุ) หรือรายการค่าสั่งซื้อ (อาร์เรย์)

อาร์กิวเมนต์ : การจัดการข้อยกเว้นไม่ควรใช้เพื่อทำสิ่งที่คาดหวัง
(นี่คือความคิดเห็นที่มีผู้โหวตมากกว่า 25 คน!)

ความจริง : ไม่! มันถูกกฎหมายที่จะใช้ลอง / จับโดยเฉพาะอย่างยิ่งในกรณีเช่นนี้ มิฉะนั้นคุณจะต้องทำสิ่งต่าง ๆ ในการวิเคราะห์สตริงเช่นการดำเนินการ tokenizing / regex ซึ่งจะมีประสิทธิภาพที่แย่มาก

hasJsonStructure()

สิ่งนี้มีประโยชน์หากเป้าหมายของคุณคือการตรวจสอบว่าข้อมูล / ข้อความบางส่วนมีรูปแบบการแลกเปลี่ยน JSON ที่เหมาะสม

function hasJsonStructure(str) {
    if (typeof str !== 'string') return false;
    try {
        const result = JSON.parse(str);
        const type = Object.prototype.toString.call(result);
        return type === '[object Object]' 
            || type === '[object Array]';
    } 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);
}

1
คุณเชื่อมโยงไปยังข้อมูลจำเพาะ JSON กล่าวว่า: "ข้อความ JSON เป็นลำดับของโทเค็นที่เกิดขึ้นจากจุดโค้ด Unicode ที่สอดคล้องกับไวยากรณ์ค่า JSON" และ "ค่า JSON สามารถเป็นวัตถุอาร์เรย์ตัวเลขสตริงจริงเท็จหรือ null ได้" - คุณได้ข้อสรุปว่า JSON สามารถเป็นวัตถุหรืออาร์เรย์ที่ระดับรูตเท่านั้นได้อย่างไร ฉันไม่เห็นสิ่งนี้ในสเป็คหรืออะไรก็ตามที่เกี่ยวข้องกับ "โครงสร้าง JSON ที่มีรูปแบบที่ดี"
#:

อ่านย่อหน้าที่สองที่ขึ้นต้นด้วย "JSON ถูกสร้างขึ้นบนสองโครงสร้าง ... " @ json.orgหรือย่อหน้าที่ 4 และ 5 ของecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf
Onur Yıldırım

json.org เป็นข้อมูลเท่านั้น การอ่านข้อมูลจำเพาะที่คุณเชื่อมโยงไปยังไม่สนับสนุนข้อเสนอแนะของคุณ ข้อมูลจำเพาะระบุว่า RFC 8259 เป็น RFC ล่าสุด ดูตัวอย่างของ texting JSON ที่ถูกต้องที่มีเฉพาะtools.ietf.org/html/rfc8259#section-13 - RFC 8259 ที่ถูกออกแบบมาเพื่อแก้ไขความสับสนและความสับสนที่อาจเกิดขึ้นเช่นนี้
ค่อนข้าง

อ่านคำตอบอีกครั้ง ฉันกำลังพูดค่าเช่น primitives (เช่นค่าข้อความในตัวอย่าง RFC) ไม่ใช่ JSON "โครงสร้าง" ไม่มีความคลุมเครือ คุณสามารถแยกพวกเขาเป็น JSON ได้ก็สามารถทำได้ แต่มันไม่ใช่โครงสร้างข้อมูล JSON ถูกประดิษฐ์ขึ้นเป็นรูปแบบการแลกเปลี่ยน»ซึ่งใช้สำหรับข้อมูลที่มีโครงสร้าง»ซึ่งอาจเป็นวัตถุหรืออาร์เรย์
Onur Yıldırım

1
ตกลงดังนั้นฉันคิดว่าเราเห็นด้วย Primatives เป็น JSON ที่ถูกต้องตามข้อกำหนด แต่ไม่ใช่ "โครงสร้าง" ไม่เป็นไร. แต่คุณพูดว่า "อาร์กิวเมนต์: ค่าเช่น true, false, null เป็น JSON ที่ถูกต้อง (?) ความจริง: ใช่และไม่ใช่!" - ข้อเท็จจริงคือ ARE JSON ที่ถูกต้องตามข้อกำหนด ความเห็นเกี่ยวกับว่าพวกเขามีประโยชน์หรือไม่ไม่เกี่ยวข้องกับข้อเท็จจริงนั้น
Relequestual

20

หากเซิร์ฟเวอร์ตอบสนองด้วย JSON ก็จะมีapplication/jsonประเภทเนื้อหาถ้ามันตอบสนองด้วยข้อความธรรมดาแล้วควรมีประเภทtext/plainเนื้อหา ตรวจสอบให้แน่ใจว่าเซิร์ฟเวอร์ตอบสนองด้วยประเภทเนื้อหาที่ถูกต้องและทดสอบว่า


4
นี่เป็นความผิดพลาด นอกจากนี้overrideMimeTypeสามารถแทนที่ส่วนหัวของประเภทเนื้อหา
Knu

14

เมื่อใช้jQuery $.ajax()การตอบกลับจะมีresponseJSONคุณสมบัติถ้าการตอบสนองเป็น JSON สิ่งนี้สามารถตรวจสอบได้ดังนี้:

if (xhr.hasOwnProperty('responseJSON')) {}

3
นี่คือฉันสงสัยว่าเป็นคำตอบที่คนส่วนใหญ่กำลังมองหาอาจจะแม้แต่ OP
Kirby

1
สิ่งนี้มีความหรูหรามากกว่าการใช้บล็อกลอง catch
Anurag Sinha

6

ฉันชอบคำตอบที่ดีที่สุด แต่ถ้ามันเป็นสตริงว่างมันจะคืนค่าจริง ดังนั้นนี่คือการแก้ไข:

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;
}

var json ไม่ได้ใช้? หรือเพียงแค่จับข้อผิดพลาด?
stackdave

5
var parsedData;

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

อย่างไรก็ตามฉันจะแนะนำให้คุณทราบว่าการโทร / บริการ http ของคุณควรส่งคืนข้อมูลในรูปแบบเดียวกันเสมอ ดังนั้นหากคุณมีข้อผิดพลาดกว่าที่คุณควรมีวัตถุ JSON ที่ห่อข้อผิดพลาดนี้:

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

และอาจใช้เป็นรหัส 5xx สถานะ HTTP


5

ดี ... มันขึ้นอยู่กับวิธีการรับข้อมูลของคุณ ฉันคิดว่าเซิร์ฟเวอร์กำลังตอบสนองด้วยสตริงที่จัดรูปแบบของ JSON (โดยใช้ json_encode () ใน PHP เช่น) หากคุณใช้โพสต์ 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',
});

เว้นแต่ของหลักสูตรที่คุณกำลังพยายามที่จะแยกข้อความข้อผิดพลาดในการทำงานข้อผิดพลาดในตัวอย่างข้างต้นและไม่แน่ใจว่ามันเป็น JSON ...
เคอร์บี้

คำตอบที่ดีแม้ว่าresponseจะว่างเปล่ามันจะไปที่success: '(
Henrik Petterson

4

อาจมีการทดสอบที่คุณสามารถทำได้ตัวอย่างเช่นถ้าคุณรู้ว่า JSON ที่ส่งคืนจะถูกล้อมรอบด้วย{และ}จากนั้นคุณสามารถทดสอบอักขระเหล่านั้นหรือวิธีการแฮ็กอื่น ๆ หรือคุณสามารถใช้ไลบรารีjson.org JS เพื่อลองแยกวิเคราะห์และทดสอบว่าสำเร็จหรือไม่

อย่างไรก็ตามฉันขอแนะนำวิธีการอื่น สคริปต์ PHP ของคุณจะส่งคืน JSON หากการโทรสำเร็จ แต่อย่างอื่นถ้าไม่ใช่ ทำไมไม่ส่งคืน JSON เสมอ

เช่น

โทรที่ประสบความสำเร็จ:

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

โทรผิดพลาด:

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

สิ่งนี้จะทำให้การเขียน JS ในฝั่งไคลเอ็นต์ของคุณง่ายยิ่งขึ้นสิ่งที่คุณต้องทำคือตรวจสอบสมาชิก "สถานะ" และการกระทำตามนั้น


4

ฉันใช้เพียง 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

ฉันได้สร้างซอสำหรับคำตอบนี้ที่jsfiddle.net/fatmonk/gpn4eyavซึ่งรวมถึงตัวเลือกในการเพิ่มข้อมูลการทดสอบผู้ใช้ของคุณเองเช่นกัน ดูเหมือนว่าพื้นฐานของฟังก์ชั่นห้องสมุดที่ดีสำหรับฉัน แต่ฉันต้องการเข้าใจเพิ่มเติมเกี่ยวกับสาเหตุที่การทดสอบ 1 ไม่ใช่อาร์เรย์ JSON ที่ถูกต้อง
Fat Monk

เพราะอาร์เรย์จะต้องระบุโดยใช้และ[ ]ตัวอย่างเช่น[1, 2, 3]เป็นอาร์เรย์ตัวเลข ["a", "b", "c"]เป็นอาร์เรย์สตริง และ[{"a":1}, {"b":2}]เป็นอาร์เรย์ JSON ดูเหมือนว่างาน jsfiddle ของคุณมีประโยชน์จริง ๆ !
efkan

ง่ายเหมือนที่! ดังนั้นการทดสอบ 1 เป็นวัตถุ JSON และการทดสอบ 2 เป็นอาร์เรย์ JSON ที่ประกอบด้วยองค์ประกอบวัตถุ JSON เดียว ฉันเข้าใจถูกต้องหรือไม่
Fat Monk

คำถามถูกตั้งค่าสถานะว่าซ้ำซ้อนกับสิ่งนี้ ( stackoverflow.com/questions/3710204/ ...... ) ถามเกี่ยวกับการบรรลุเป้าหมายนี้โดยไม่ต้องใช้การลอง / จับดังนั้นฉันจึงใช้มือขวาเพื่อบรรลุเป้าหมายนั้นเช่นกัน ส้อมที่jsfiddle.net/fatmonk/827jsuvrและทำงานร่วมกับการทดสอบทั้งหมดข้างต้นยกเว้นสำหรับการทดสอบ 3 JSON.parseซึ่งข้อผิดพลาดที่ ทุกคนสามารถแนะนำวิธีหลีกเลี่ยงข้อผิดพลาดนั้นได้โดยไม่ต้องลอง
Fat Monk

jsfiddleแอปพลิเคชันของคุณส่งข้อผิดพลาดเนื่องจากการทดสอบ 3 ไม่มีนิพจน์ JSON ที่ถูกต้อง ดังนั้นtry-catchต้องใช้เพื่อตรวจจับข้อผิดพลาดนั้นและประเมินข้อผิดพลาดใด ๆ เนื่องจากนิพจน์ไม่ใช่ JSON เมื่อวิเคราะห์เหมือนการทดสอบ 3 ด้านบน:try { JSON.parse(data3) } catch(e) { isValidJSON = false }
efkan

2

คุณสามารถลองถอดรหัสมันและตรวจจับข้อยกเว้น (เนทีฟหรือ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

คำเตือน:สำหรับวิธีการที่ต้องพึ่งพาJSON.parse- อาร์เรย์และเครื่องหมายคำพูดที่ล้อมรอบสตริงจะส่งผ่านเช่นกัน (เช่นconsole.log(JSON.parse('[3]'), JSON.parse('"\uD800"')))

เพื่อหลีกเลี่ยงดั้งเดิม JSON ไม่ใช่วัตถุทั้งหมด (บูลีน, null, อาร์เรย์, ตัวเลข, สตริง) ผมขอแนะนำให้ใช้ต่อไปนี้:

/* Validate a possible object ie. o = { "a": 2 } */
const isJSONObject = (o) => 
  !!o && (typeof o === 'object') && !Array.isArray(o) && 
  (() => { try { return Boolean(JSON.stringify(o)); } catch { return false } })()

/* Validate a possible JSON object represented as string ie. s = '{ "a": 3 }' */
function isJSONObjectString(s) {
    try {
        const o = JSON.parse(s);
        return !!o && (typeof o === 'object') && !Array.isArray(o)
    } catch {
        return false
    }
}

รหัสคำอธิบาย

  • !! o - ไม่ผิดพลาด (ไม่รวมค่า null ซึ่งลงทะเบียนเป็น typeof 'object')
  • (typeof o === 'object') - ยกเว้นบูลีน, ตัวเลขและสตริง
  • ! Array.isArray (o) - ยกเว้นอาร์เรย์ (ซึ่งลงทะเบียนเป็น typeof 'object')
  • ลอง ... JSON.stringify / JSON.parse - ถามเครื่องมือ JavaScript เพื่อตรวจสอบว่า JSON ที่ถูกต้อง

ทำไมไม่ใช้คำตอบ hasJsonStructure ()

การพึ่งพาtoString()ไม่ใช่ความคิดที่ดี นี่เป็นเพราะเอ็นจิน JavaScript ที่แตกต่างกันอาจส่งคืนการแทนสตริงที่แตกต่าง โดยทั่วไปวิธีการที่ใช้สิ่งนี้อาจล้มเหลวในสภาพแวดล้อมที่แตกต่างกันหรืออาจมีความล้มเหลวในภายหลังหากเครื่องยนต์เปลี่ยนผลลัพธ์สตริง

ทำไมการจับข้อยกเว้นไม่ใช่แฮ็ค

มันถูกนำมาขึ้นที่จับข้อยกเว้นเพื่อตรวจสอบความถูกต้องของสิ่งที่ไม่เคยไปทางที่ถูกต้อง นี่เป็นคำแนะนำที่ดี แต่ไม่เสมอไป ในกรณีนี้การตรวจจับข้อยกเว้นนั้นเป็นเส้นทางที่ดีที่สุดเพราะอาศัยการใช้งานเครื่องมือ JavaScript ในการตรวจสอบความถูกต้องของข้อมูล JSON

การใช้เอ็นจิน JS มีข้อดีดังต่อไปนี้:

  1. ละเอียดยิ่งขึ้นและทันสมัยขึ้นอย่างต่อเนื่องเมื่อการเปลี่ยนแปลงข้อมูลจำเพาะของ JSON
  2. มีแนวโน้มที่จะทำงานได้เร็วขึ้น (เนื่องจากเป็นรหัสระดับต่ำกว่า)

เมื่อได้รับโอกาสที่จะพึ่งพาเอนจิ้น JavaScript ฉันขอแนะนำให้ทำ โดยเฉพาะอย่างยิ่งในกรณีนี้ แม้ว่ามันอาจรู้สึกแฮ็คที่จะจับข้อยกเว้นคุณเป็นเพียงแค่การจัดการสองรัฐกลับเป็นไปได้จากวิธีการภายนอก


1

นี่คือรหัสที่มีการดัดแปลงเล็กน้อยในคำตอบของ Bourne ในฐานะที่เป็น JSON.parse (ตัวเลข) ทำงานได้ดีโดยไม่มีข้อยกเว้นดังนั้นเพิ่ม isNaN

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

0

สตริง 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


@DukeDougal สนใจที่จะชี้แจงหรือไม่ บางครั้งผู้คนเริ่ม json ด้วย '[' แต่นั่นไม่ใช่เรื่องธรรมดามาก
carlin.scott

1
คุณต้องแยกวิเคราะห์เพื่อให้ได้ผลซึ่งเป็น JSON ที่ถูกต้อง หากเป็น JSON ที่ไม่ถูกต้องแสดงว่าไม่ใช่ JSON คำถามคือ "บอกได้อย่างไรว่าสตริงเป็น JSON หรือไม่" โดยวิธีการของคุณนี้จะ JSON {fibble - และไม่ใช่ JSON พิจารณากรณีต่างๆเช่นหมายเลข 1 ด้วยตัวของมันเอง - นั่นคือ JSON ที่ถูกต้อง
Duke Dougal

1
"ถ้ามันเป็น JSON ที่ไม่ถูกต้องแสดงว่าไม่ใช่ JSON" ความจริงที่ว่าคุณต้องใช้คำว่า "ถูกต้อง" แสดงให้เห็นว่าคุณกำลังเพิ่มคุณสมบัติให้กับความจริงที่ว่ามันเป็นมากกว่าแค่ json คำถามก็คือ "is it json" และตัวอย่างรหัสของฉันตอบคำถามนั้นอย่างสมบูรณ์แบบโดยไม่ต้องมีข้อกำหนดเพิ่มเติม
carlin.scott

แนวคิดที่ไม่ดีถ้าคุณใช้ระบบเทมเพลตบางระบบและคุณมีสิ่งที่ชอบ{ someValue }จะผ่านการตรวจสอบโดยอัตโนมัติ
ncubica

@ncubica ดังนั้นคุณจึงใช้เทมเพลตสำหรับสิ่งอื่นที่ไม่ใช่ json, สตริงมีตัวยึดที่ใช้เครื่องหมายปีกกาเท่านั้นและเอ็นจิ้นแม่แบบไม่สามารถแทนที่ตัวยึดตำแหน่งด้วยค่าจริงได้หรือไม่ โปรดจำไว้ว่าอย่างที่ฉันอธิบายให้ Duke แล้วคำถามเดิมไม่ได้กล่าวถึงการตรวจสอบ พวกเขาแค่อยากรู้ว่ามันดูเหมือน json หรือไม่
carlin.scott

0

ฉันแนะนำในโหมด typescript:

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

0

ฉันใช้อันนี้ (เป็นคำตอบที่แตกต่างกันหลายอย่างรวมกัน):

const isJSON = str => {
  if (typeof str === 'string'){
    try {
      JSON.parse(str)
      return true
    } catch(e){
    }
  }
  return false
}



[null, undefined, false, true, [], {}, 
 '', 'asdf', '{}', '[]', "{\"abc\": 2}","{\"abc\": \"2\"}"]
  .map(el => {
      console.log(`[>${el}<] - ${isJSON(el)}`)
})

console.log('-----------------')


0

คุณสามารถลองใช้สิ่งต่อไปนี้ได้เพราะมันยังตรวจสอบความถูกต้องของตัวเลข, โมฆะ, สตริง แต่คำตอบที่ทำเครื่องหมายไว้ด้านบนนั้นไม่ทำงานอย่างถูกต้องมันเป็นเพียงการแก้ไขฟังก์ชั่นด้านบน:

function isJson(str) {
  try {
      const obj = JSON.parse(str);
      if (obj && typeof obj === `object`) {
        return true;
      }
    } catch (err) {
      return false;
    }
   return false;
}

-1

นอกจากคำตอบก่อนหน้านี้ในกรณีที่คุณต้องการตรวจสอบรูปแบบ JSON เช่น "{}" คุณสามารถใช้รหัสต่อไปนี้:

const validateJSON = (str) => {
  try {
    const json = JSON.parse(str);
    if (Object.prototype.toString.call(json).slice(8,-1) !== 'Object') {
      return false;
    }
  } catch (e) {
    return false;
  }
  return true;
}

ตัวอย่างการใช้งาน:

validateJSON('{}')
true
validateJSON('[]')
false
validateJSON('')
false
validateJSON('2134')
false
validateJSON('{ "Id": 1, "Name": "Coke" }')
true
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.