AJAX: Kiểm tra xem một chuỗi có phải là JSON không?


83

JavaScript của tôi đôi khi gặp sự cố trên dòng này:

var json = eval('(' + this.responseText + ')');

Sự cố xảy ra khi đối số của eval()không phải là JSON. Có cách nào để kiểm tra xem chuỗi có phải là JSON không trước khi thực hiện cuộc gọi này?

Tôi không muốn sử dụng một khuôn khổ - có cách nào để làm cho công việc này chỉ bằng cách sử dụng eval()không? (Tôi hứa là có lý do chính đáng.)


Bạn có thể thử JSON.parse () trong một lần thử / bắt ... nếu bạn bắt được, thì đánh dấu JSON không hợp lệ của nó. Tất nhiên, điều đó hơi kém hiệu quả, heh ... Bạn có thể cho tôi một ví dụ về đánh dấu JSON không hợp lệ mà bạn đang nhận được không?
Warty

Câu trả lời:


157

Nếu bạn bao gồm trình phân tích cú pháp JSON từ json.org, bạn có thể sử dụng hàm phân tích cú pháp () của nó và chỉ cần gói nó trong một lần thử / bắt, như sau:

try
{
   var json = JSON.parse(this.responseText);
}
catch(e)
{
   alert('invalid json');
}

Một cái gì đó như vậy có thể sẽ làm những gì bạn muốn.


9
sử dụng jQuery.parseJSON (..), bạn sẽ không cần phải bao gồm json.org
RayLoveless

1
@Raymo OP không đề cập đến việc sử dụng jQuery và json2.js nhỏ hơn một nửa kích thước của jQuery (về kích thước tệp).
brettkelly

Phân tích toàn bộ một chuỗi là xấu thực hành, và ném một ngoại lệ có thể gây lag
hương thơm

nó sẽ không ném một ngoại lệ nếu bạn gửi một chuỗi số
Hesham Yassin

21

Hers là giải pháp thay thế jQuery ...

try
{
  var jsonObject = jQuery.parseJSON(yourJsonString);
}
catch(e)
{
  // handle error 
}

15

Tôi thực sự khuyên bạn nên sử dụng thư viện javascript JSON để tuần tự hóa đến và từ JSON. eval()là một rủi ro bảo mật không bao giờ được sử dụng trừ khi bạn hoàn toàn chắc chắn rằng đầu vào của nó đã được khử trùng và an toàn.

Với thư viện JSON tại chỗ, chỉ cần gói lệnh gọi parse()tương đương với nó trong một khối try / catch-block để xử lý đầu vào không phải JSON:

try
{
  var jsonObject = JSON.parse(yourJsonString);
}
catch(e)
{
  // handle error 
}

2

Có thể điều này hữu ích: Với mã này, bạn có thể nhận trực tiếp dữ liệu của mình…

<!DOCTYPE html>
<html>
<body>

<h3>Open console, please, to view result!</h3>
<p id="demo"></p>

<script>
var tryJSON = function (test) {
	try {
	    JSON.parse(test);
	}
	catch(err) {
    	// maybe you need to escape this… (or not)
	    test = '"'+test.replace(/\\?"/g,'\\"')+'"';
	}
	eval('test = '+test);
	console.debug('Try json:', test);
};

// test with string…
var test = 'bonjour "mister"';
tryJSON(test);
// test with JSON…
var test = '{"fr-FR": "<p>Ceci est un texte en français !</p>","en-GB": "<p>And here, a text in english!</p>","nl-NL": "","es-ES": ""}';
tryJSON(test);
</script>

</body>
</html>


Có rất nhiều cách thay thế để đạt được kết quả tương tự, sử dụng eval () có lẽ là cách ít thích hợp nhất.
David

0

Vấn đề với việc tùy thuộc vào try-catchcách tiếp cận là như vậy JSON.parse('123') = 123và nó sẽ không có ngoại lệ. Do đó, ngoài các try-catch, chúng ta cần kiểm tra loại như sau:

function isJsonStr(str) {
    var parsedStr = str;
    try {
        parsedStr = JSON.parse(str);
    } catch (e) {
        return false;
    }
    return typeof parsedStr == 'object'
}

0

Tại sao bạn không thể chỉ kiểm tra phản hồi là gì? Nó hiệu quả hơn.

var result;

if (response.headers['Content-Type'] === 'application/json')
    result = JSON.parse(this.responseText);
else
    result = this.responseText;

screen1


-1

Có một thư viện nhỏ kiểm tra các loại JavaScript: is.js

is.json({foo: 'bar'});
=> true

// functions are returning as false
is.json(toString);
=> false

is.not.json([]);
=> true

is.all.json({}, 1);
=> false

is.any.json({}, 2);
=> true

// 'all' and 'any' interfaces can also take array parameter
is.all.json([{}, {foo: 'bar'}]);
=> true

Trên thực tế is.js còn nhiều hơn thế này, một số đề cập danh dự:

var obj = document.createElement('div');
is.domNode(obj);
=> true

is.error(new Error());
=> true

is.function(toString);
=> true

is.chrome();
=> true if current browser is chrome


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.