Làm cách nào để gửi JSON thay vì chuỗi truy vấn bằng $ .ajax?


172

Ai đó có thể giải thích một cách dễ dàng cách làm cho jQuery gửi JSON thực tế thay vì chuỗi truy vấn không?

$.ajax({
    url      : url,
    dataType : 'json', // I was pretty sure this would do the trick
    data     : data,
    type     : 'POST',
    complete : callback // etc
});

Thực tế, điều này sẽ chuyển đổi JSON được chuẩn bị cẩn thận của bạn thành một chuỗi truy vấn. Một trong những điều khó chịu là bất kỳ array: []đối tượng nào trong đối tượng của bạn sẽ được chuyển đổi thành array[]: [], có thể là do các giới hạn của sting truy vấn.


7
Không dataTypecó liên quan đến cách dữ liệu được gửi. Nó chỉ xác định loại dữ liệu mà bạn mong đợi đã được trả về bởi cuộc gọi. Nếu bạn muốn chỉ cho máy chủ biết loại dữ liệu nào bạn đang chỉ định trong thuộc datatính bạn cần để đặt thuộc contentTypetính tương tựcontentType: "application/json"
Không,

Cảm ơn đã làm rõ. Nhưng trong trường hợp đó, tại sao tôi cần chỉ định phía máy khách loại phản hồi nếu máy chủ đang cung cấp tiêu đề loại nội dung trong phản hồi?
Redsandro

2
Bạn không cần phải chỉ định nó, theo mặc định jQuery sẽ thử và đưa ra dự đoán thông minh dựa trên loại phản hồi MIME. Tuy nhiên, bằng cách chỉ định nó, bạn đang nói với jQuery một cách rõ ràng loại mà bạn đang mong đợi từ máy chủ và jQuery sẽ cố gắng chuyển đổi phản hồi thành một đối tượng thuộc loại đó. Không chỉ định nó và để jQuery đoán, có thể dẫn đến việc jQuery chuyển đổi phản hồi thành định dạng không mong muốn, ngay cả khi bạn đã gửi JSON từ máy chủ. Kiểm tra tài liệu để biết thêm chi tiết về dataType: api.jquery.com/jQuery.ajax
Không,

Câu trả lời:


256

Trước tiên, bạn cần sử dụng JSON.stringifyđể tuần tự hóa đối tượng của mình thành JSON và sau đó chỉ định contentTypeđể máy chủ của bạn hiểu JSON của nó. Cái này cần phải dùng mẹo:

$.ajax({
    url: url,
    type: "POST",
    data: JSON.stringify(data),
    contentType: "application/json",
    complete: callback
});

Lưu ý rằng JSONđối tượng thực sự có sẵn trong các trình duyệt hỗ trợ JavaScript 1.7 / ECMAScript 5 trở lên. Nếu bạn cần hỗ trợ kế thừa, bạn có thể sử dụng json2 .


14
Điều này sẽ không hoạt động, bạn đang thiếu contentType: 'application/json'.
Ohgodwhy

@Ohgodwhy ồ. Điều đó đã đi hơi nhanh;)
mekwall

1
Cảm ơn. Tôi nghĩ dataType đã quan tâm đến điều này, nhưng tôi đã nhận được điều đó ngược lại. Bạn có suy nghĩ gì về việc chỉ định bộ ký tự theo kiểu nội dung như Bergi đã làm trong câu trả lời khác không?
Redsandro

5
@Redsandro Điều đó không cần thiết. Theo tài liệu jQuery:POST data will always be transmitted to the server using UTF-8 charset, per the W3C XMLHTTPRequest standard
mekwall

1
@ shorif2000 muộn còn hơn không bao giờ ... vấn đề là $_POSTtrong php bạn chỉ có thể nhìn thấy application/x-www-form-urlencoded, nếu bạn muốn đọc dữ liệu json bạn phải làm file_get_contents("php://input")và có lẽ sau đó là mộtjson_decode()
santiago arizti 23/11/18

28

Không, dataTypetùy chọn này là để phân tích dữ liệu nhận được.

Để đăng JSON, bạn sẽ cần tự xâu chuỗi nó thông qua JSON.stringifyvà đặt processDatatùy chọn thành false.

$.ajax({
    url: url,
    type: "POST",
    data: JSON.stringify(data),
    processData: false,
    contentType: "application/json; charset=UTF-8",
    complete: callback
});

Lưu ý rằng không phải tất cả các trình duyệt đều hỗ trợ JSONđối tượng và mặc dù jQuery có .parseJSON, nhưng nó không có trình sắp xếp chuỗi bao gồm; bạn sẽ cần một thư viện polyfill khác.


4
Thiết processDatađến falselà không cần thiết vì JSON.stringifyđã trả về một chuỗi.
mekwall

@MarcusEkwall: Afaik nó vẫn sẽ là encodeURIComponented, phải không?
Bergi

OK, nó có thể không cần thiết, nhưng bạn có thực sự nghĩ rằng nó sẽ làm cho yêu cầu thất bại?
Bergi

Nó không nên làm cho nó thất bại, coi đó là một chuỗi.
Kevin B

1
@Redsandro: Vâng, đó là một "dự đoán thông minh". Tuy nhiên, lý do cho tham số không phải (chỉ) là mọi người muốn làm cho nó nghiêm ngặt, mà hơn nữa là họ không đặt các loại MIME phù hợp trong phản hồi máy chủ của họ.
Bergi

5

Mặc dù tôi biết nhiều kiến ​​trúc như ASP.NET MVC có chức năng tích hợp sẵn để xử lý JSON.opesify vì nội dung Loại tình huống của tôi hơi khác một chút nên có thể điều này có thể giúp đỡ ai đó trong tương lai. Tôi biết nó sẽ giúp tôi tiết kiệm hàng giờ!

Vì các yêu cầu http của tôi đang được xử lý bởi API CGI từ IBM (môi trường AS400) trên một tên miền phụ khác, các yêu cầu này có nguồn gốc chéo, do đó là jsonp. Tôi thực sự gửi ajax của mình thông qua (các) đối tượng javascript. Đây là một ví dụ về ajax POST của tôi:

 var data = {USER : localProfile,  
        INSTANCE : "HTHACKNEY",  
        PAGE : $('select[name="PAGE"]').val(), 
        TITLE : $("input[name='TITLE']").val(), 
        HTML : html,
        STARTDATE : $("input[name='STARTDATE']").val(), 
        ENDDATE : $("input[name='ENDDATE']").val(),
        ARCHIVE : $("input[name='ARCHIVE']").val(), 
        ACTIVE : $("input[name='ACTIVE']").val(), 
        URGENT : $("input[name='URGENT']").val(), 
        AUTHLST :  authStr};
        //console.log(data);
       $.ajax({
            type: "POST",
           url:   "http://www.domian.com/webservicepgm?callback=?",
           data:  data,
           dataType:'jsonp'
       }).
       done(function(data){
         //handle data.WHATEVER
       });

2
Cảm ơn đã bổ sung thêm kiến ​​thức cho câu hỏi này! Câu trả lời thỏa mãn đã được đưa ra, nhưng tôi đánh giá cao câu trả lời của bạn.
Redsandro

1

Nếu bạn đang gửi lại thông tin này cho asp.net và cần dữ liệu trong request.form [] thì bạn sẽ cần đặt loại nội dung thành "application / x-www-form-urlencoding; charset = utf-8"

Bài gốc ở đây

Thứ hai hãy thoát khỏi Datatype, nếu bạn không mong đợi sự trở lại, POST sẽ đợi khoảng 4 phút trước khi thất bại. Xem tại đây

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.