Việc khử lưu lượng JSON thành một đối tượng JavaScript


266

Tôi có một chuỗi trong ứng dụng máy chủ Java được truy cập bằng AJAX. Nó trông giống như sau:

var json = [{
    "adjacencies": [
        {
          "nodeTo": "graphnode2",
          "nodeFrom": "graphnode1",
          "data": {
            "$color": "#557EAA"
          }
        }
    ],
    "data": {
      "$color": "#EBB056",
      "$type": "triangle",
      "$dim": 9
    },
    "id": "graphnode1",
    "name": "graphnode1"
},{
    "adjacencies": [],
    "data": {
      "$color": "#EBB056",
      "$type": "triangle",
      "$dim": 9
    },
    "id": "graphnode2",
    "name": "graphnode2"
}];

Khi chuỗi được kéo từ máy chủ, có cách nào dễ dàng để biến chuỗi này thành đối tượng JavaScript (hoặc mảng) không? Hoặc tôi phải tự tách chuỗi và xây dựng đối tượng của mình theo cách thủ công?



Có thể trùng lặp Parse JSON trong JavaScript?
m93a

Câu trả lời:


397

Hỗ trợ trình duyệt hiện đại JSON.parse().

var arr_from_json = JSON.parse( json_string );

Trong các trình duyệt mà không làm, bạn có thể bao gồm các json2thư viện .


Làm thế nào điều đó sẽ hoạt động cho các trường ngày trong JSON, ví dụ {StartDate: "\ / Date (1372575600000) \ /"}?
Philipp Munin

@PhilippMunin bạn có thể sử dụng chức năng Ngày này từ API javascript: Ngày mới (parseInt ("/ Ngày (946681200000) /". Thay thế ('/ Ngày (', '')));
Leo

hoặc các đối tượng Map (), v.v., làm thế nào để bạn thực hiện khử lưu huỳnh thích hợp
Ewan

25

Điểm chung của JSON là các chuỗi JSON có thể được chuyển đổi thành các đối tượng gốc mà không cần làm gì cả. Kiểm tra liên kết này

Bạn có thể sử dụng eval(string)hoặc JSON.parse(string).

Tuy nhiên, evallà rủi ro. Từ json.org:

Chức năng eval rất nhanh. Tuy nhiên, nó có thể biên dịch và thực thi bất kỳ chương trình JavaScript nào, do đó có thể có các vấn đề bảo mật. Việc sử dụng eval được chỉ định khi nguồn đáng tin cậy và có thẩm quyền. An toàn hơn nhiều khi sử dụng trình phân tích cú pháp JSON. Trong các ứng dụng web qua XMLHttpRequest, giao tiếp chỉ được phép cho cùng một nguồn gốc cung cấp trang đó, vì vậy nó được tin cậy. Nhưng nó có thể không có thẩm quyền. Nếu máy chủ không nghiêm ngặt trong mã hóa JSON hoặc nếu nó không xác thực nghiêm ngặt tất cả các đầu vào của nó, thì nó có thể cung cấp văn bản JSON không hợp lệ có thể mang tập lệnh nguy hiểm. Hàm eval sẽ thực thi tập lệnh, giải phóng ác ý của nó.


1
Tôi không hiểu rủi ro. Không ai có thể sử dụng trình gỡ lỗi js để tiêm và thực thi bất kỳ tập lệnh nào họ muốn?
xr280xr

3
@ xr280xr Có, nhưng điều đó chỉ xảy ra cục bộ trong trình duyệt của họ, không phải mọi trình duyệt tải xuống trang web.
masterxilo

16

Làm như jQuery nào! (bản chất)

function parseJSON(data) {
    return window.JSON && window.JSON.parse ? window.JSON.parse( data ) : (new Function("return " + data))(); 
}
// testing
obj = parseJSON('{"name":"John"}');
alert(obj.name);

Bằng cách này, bạn không cần bất kỳ thư viện bên ngoài nào và nó vẫn hoạt động trên các trình duyệt cũ.


7
Điều này có vẻ như nó trở lại tương đương với eval().
LarsH

1
Điều này là nguy hiểm, eval là xấu xa!
caesarsol

8

Để thu thập tất cả các mục của một mảng và trả về một đối tượng json

collectData: function (arrayElements) {

        var main = [];

        for (var i = 0; i < arrayElements.length; i++) {
            var data = {};
            this.e = arrayElements[i];            
            data.text = arrayElements[i].text;
            data.val = arrayElements[i].value;
            main[i] = data;
        }
        return main;
    },

Để phân tích cùng một dữ liệu chúng ta trải qua như thế này

dummyParse: function (json) {       
        var o = JSON.parse(json); //conerted the string into JSON object        
        $.each(o, function () {
            inner = this;
            $.each(inner, function (index) {
                alert(this.text)
            });
        });

}

4

Bạn cũng có thể sử dụng eval()nhưng cách JSON.parse()an toàn và dễ dàng hơn, vậy tại sao bạn lại như vậy?

tốt và làm việc

var yourJsonObject = JSON.parse(json_as_text);

Tôi không thấy bất kỳ lý do tại sao bạn muốn sử dụng eval. Nó chỉ đặt ứng dụng của bạn có nguy cơ.

Điều đó nói rằng - đây cũng có thể.

xấu - nhưng cũng hoạt động

var yourJsonObject = eval(json_as_text);

Tại sao là evalmột ý tưởng tồi?

Hãy xem xét ví dụ sau.

Một số bên thứ ba hoặc người dùng đã cung cấp dữ liệu chuỗi JSON.

var json = `
[{
    "adjacencies": [
        {
          "nodeTo": function(){
            return "delete server files - you have been hacked!";
          }(),
          "nodeFrom": "graphnode1",
          "data": {
            "$color": "#557EAA"
          }
        }
    ],
    "data": {
      "$color": "#EBB056",
      "$type": "triangle",
      "$dim": 9
    },
    "id": "graphnode1",
    "name": "graphnode1"
},{
    "adjacencies": [],
    "data": {
      "$color": "#EBB056",
      "$type": "triangle",
      "$dim": 9
    },
    "id": "graphnode2",
    "name": "graphnode2"
}]
`;

Kịch bản phía máy chủ của bạn xử lý dữ liệu đó.

Sử dụng JSON.parse:

window.onload = function(){
  var placeholder = document.getElementById('placeholder1');
  placeholder.innerHTML = JSON.parse(json)[0].adjacencies[0].nodeTo;
}

sẽ ném:

Uncaught SyntaxError: Unexpected token u in JSON at position X. 

Chức năng sẽ không được thực thi.

Bạn an toàn rồi.

Sử dụng eval():

window.onload = function(){
  var placeholder = document.getElementById('placeholder1');
  placeholder.innerHTML = eval(json)[0].adjacencies[0].nodeTo;
}

sẽ thực thi chức năng và trả về văn bản.

Nếu tôi thay thế chức năng vô hại đó bằng chức năng xóa các tệp khỏi thư mục trang web của bạn, bạn đã bị hack. Không có lỗi / cảnh báo sẽ bị ném trong ví dụ này.

Bạn KHÔNG an toàn.

Tôi đã có thể thao tác một chuỗi văn bản JSON để nó hoạt động như một hàm sẽ thực thi trên máy chủ.

eval(JSON)[0].adjacencies[0].nodeTo mong đợi xử lý một chuỗi JSON nhưng trên thực tế, chúng tôi chỉ thực hiện một chức năng trên máy chủ của mình.

Điều này cũng có thể được ngăn chặn nếu phía máy chủ của chúng tôi kiểm tra tất cả dữ liệu do người dùng cung cấp trước khi chuyển nó sang một eval()chức năng nhưng tại sao không sử dụng công cụ tích hợp để phân tích JSON và tránh tất cả những rắc rối và nguy hiểm này?


1

Và nếu bạn cũng muốn đối tượng khử lưu huỳnh có chức năng, bạn có thể sử dụng công cụ nhỏ của tôi: https://github.com/khayll/jsmix

//first you'll need to define your model
var GraphNode = function() {};
GraphNode.prototype.getType = function() {
   return this.$type;
}

var Adjacency = function() {};
Adjacency.prototype.getData =n function() {
    return this.data;
}

//then you could say:
var result = JSMix(jsonData)
    .withObject(GraphNode.prototype, "*")
    .withObject(Adjacency.prototype, "*.adjacencies")
    .build();

//and use them
console.log(result[1][0].getData());

0

Nếu bạn dán chuỗi ở phía máy chủ vào html thì không cần làm gì:

Đối với java đơn giản trong jsp:

var jsonObj=<%=jsonStringInJavaServlet%>;

Đối với thanh chống chiều rộng jsp:

var jsonObj=<s:property value="jsonStringInJavaServlet" escape="false" escapeHtml="false"/>;

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.