วิธีการส่ง JSON แทนที่จะเป็นสตริงการสืบค้นด้วย $ .ajax


172

ใครสามารถอธิบายวิธีง่ายๆในการทำให้ jQuery ส่ง JSON จริงแทนที่จะเป็นสตริงข้อความค้นหา

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

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


7
dataTypeไม่มีผลต่อวิธีการที่ข้อมูลจะถูกส่งไป มันเป็นเพียงการระบุชนิดของข้อมูลที่ถูกคุณคาดว่าจะได้กลับมาจากการเรียกร้อง หากคุณต้องการระบุให้เซิร์ฟเวอร์ทราบว่าคุณใช้ข้อมูลประเภทใดในdataคุณสมบัติคุณต้องตั้งค่าcontentTypeคุณสมบัติคล้ายกับcontentType: "application/json"
Nope

ขอบคุณสำหรับการชี้แจง แต่ในกรณีนั้นเหตุใดฉันต้องระบุชนิดการตอบกลับฝั่งไคลเอ็นต์หากเซิร์ฟเวอร์ระบุส่วนหัวชนิดเนื้อหาในการตอบกลับ
Redsandro

2
คุณไม่จำเป็นต้องระบุโดยค่าเริ่มต้น jQuery จะพยายามเดาอย่างชาญฉลาดตามประเภทการตอบสนองของ MIME อย่างไรก็ตามโดยการระบุว่าคุณกำลังบอก jQuery อย่างชัดเจนว่าคุณคาดหวังอะไรจากเซิร์ฟเวอร์และ jQuery จะพยายามแปลงการตอบสนองเป็นวัตถุประเภทนั้น การไม่ระบุและปล่อยให้ jQuery คาดเดาอาจส่งผลให้ jQuery แปลงการตอบกลับเป็นรูปแบบที่ไม่คาดคิดแม้ว่าคุณจะส่ง JSON จากเซิร์ฟเวอร์ ตรวจสอบเอกสารประกอบสำหรับรายละเอียดเพิ่มเติมเกี่ยวกับ dataType: api.jquery.com/jQuery.ajax
Nope

คำตอบ:


256

คุณต้องใช้JSON.stringifyเพื่อทำให้เป็นอันดับวัตถุของคุณเป็น JSON แล้วระบุว่าcontentTypeเซิร์ฟเวอร์ของคุณเข้าใจว่าเป็น JSON สิ่งนี้ควรทำเคล็ดลับ:

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

โปรดทราบว่าJSONวัตถุนั้นมีอยู่ในเบราว์เซอร์ที่รองรับ JavaScript 1.7 / ECMAScript 5 หรือใหม่กว่า หากคุณต้องการการสนับสนุนมรดกคุณสามารถใช้json2


14
contentType: 'application/json'นี้จะไม่ทำงานคุณกำลังขาดหายไป
Ohgodwhy

@Ohgodwhy โอ้ใช่แล้ว มันเร็วไปหน่อย;)
mekwall

1
ขอบคุณ ฉันคิดว่า DataType ดูแลสิ่งนี้ แต่ฉันกลับไปข้างหลัง มีความคิดเห็นเกี่ยวกับการระบุชุดอักขระในประเภทเนื้อหาเช่น Bergi หรือไม่ในคำตอบอื่น ๆ
Redsandro

5
@ Reedandro นั่นไม่น่าจะจำเป็น ตามเอกสาร jQuery:POST data will always be transmitted to the server using UTF-8 charset, per the W3C XMLHTTPRequest standard
mekwall

1
@ shorif2000 ดีกว่าไม่สาย ... ปัญหาคือ$_POSTใน php คุณสามารถดูapplication/x-www-form-urlencodedได้ถ้าคุณต้องการอ่านข้อมูล json คุณต้องทำfile_get_contents("php://input")และบางที ajson_decode()
santiago arizti

28

ไม่dataTypeตัวเลือกนี้ใช้สำหรับการแยกวิเคราะห์ข้อมูลที่ได้รับ

เพื่อโพสต์ JSON, คุณจะต้อง stringify มันด้วยตัวเองผ่านทางJSON.stringifyและการตั้งค่าตัวเลือกในการprocessDatafalse

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

โปรดทราบว่าไม่ใช่ทุกเบราว์เซอร์ที่รองรับJSONวัตถุและถึงแม้ว่า jQuery จะมี.parseJSONแต่มันก็ไม่ได้รวมสตริงสตริง คุณจะต้องมีห้องสมุด polyfill อื่น


4
การตั้งค่าprocessDataจะfalseไม่จำเป็นตั้งแต่JSON.stringifyแล้วส่งกลับสตริง
mekwall

@MarcusEkwall: Afaik มันยังคงเป็นencodeURIComponented อยู่ใช่ไหม?
Bergi

ตกลงอาจไม่จำเป็น แต่คุณคิดว่ามันจะทำให้การร้องขอล้มเหลวหรือไม่?
Bergi

มันไม่ควรทำให้มันล้มเหลวเพราะมันเป็นสตริงแล้ว
Kevin B

1
@ Reddandro: ใช่มันกำลังทำ "เดาอัจฉริยะ" อย่างไรก็ตามเหตุผลสำหรับพารามิเตอร์ไม่ได้เป็น (คนเดียว) ที่ผู้คนต้องการทำให้มันเข้มงวด แต่ยิ่งกว่านั้นพวกเขาไม่ได้ตั้งค่าประเภท MIME ที่เหมาะสมในการตอบกลับของเซิร์ฟเวอร์
Bergi

5

ในขณะที่ฉันรู้สถาปัตยกรรมหลายอย่างเช่น ASP.NET MVC มีฟังก์ชันการทำงานในตัวเพื่อจัดการ JSON.stringify เนื่องจาก contentType สถานการณ์ของฉันแตกต่างกันเล็กน้อยดังนั้นบางทีนี่อาจช่วยคนในอนาคต ฉันรู้ว่ามันจะช่วยให้ฉันชั่วโมง!

เนื่องจากคำขอ HTTP ของฉันถูกจัดการโดย CGI API จาก IBM (สภาพแวดล้อม AS400) ในโดเมนย่อยที่แตกต่างกันคำขอเหล่านี้จึงเป็นจุดกำเนิดไขว้ดังนั้น jsonp ฉันส่งอาแจ็กซ์ของฉันผ่านทางวัตถุจาวาสคริปต์ นี่คือตัวอย่างของ Ajax POST ของฉัน:

 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
ขอขอบคุณที่เพิ่มความรู้ให้กับคำถามนี้! คำตอบที่น่าพอใจได้รับแล้ว แต่ฉัน upvoting ของคุณ
Redsandro

1

หากคุณส่งกลับไปที่ asp.net และต้องการข้อมูลใน request.form [] คุณจะต้องตั้งค่าประเภทเนื้อหาเป็น "application / x-www-form-urlencoded; charset = utf-8"

โพสต์ต้นฉบับที่นี่

กำจัดประเภทข้อมูลที่สองหากคุณไม่คาดหวังว่าจะได้รับคืน POST จะรอประมาณ 4 นาทีก่อนที่จะล้มเหลว ดูที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.