Header Jenis Konten HTTP dan JSON

144

Saya selalu berusaha menghindari penggunaan sebagian besar properti protokol HTTP demi takut akan hal yang tidak diketahui.

Namun, saya berkata pada diri sendiri bahwa saya akan menghadapi ketakutan hari ini dan mulai menggunakan header dengan sengaja. Saya telah mencoba mengirim jsondata ke browser dan langsung menggunakannya. Misalnya, jika saya memiliki fungsi penangan Ajax pada status siap 4 yang terlihat seperti ini:

function ajaxHandler(response){
    alert(response.text);
}

Dan saya telah mengatur header tipe konten dalam kode PHP saya:

header('Content-Type: application/json');
echo json_encode(array('text' => 'omrele'));

Mengapa saya tidak bisa langsung mengakses properti dari fungsi handler, ketika browser dengan jelas diberitahu bahwa data yang masuk adalah application/json?

php_nub_qq
sumber
Jika saya mengerti dengan benar, Anda ingin menggunakan textsebagai variabel javascript di handler dan bukan respons? Itu akan menjadi fungsi yang sangat aneh. The json_encode juga membuat 1 objek dari array PHP Anda. Jadi, ketika Anda memasukkan ini ke dalam javascript, Anda harus ditugaskan ke variabel.
Flashin
4
Header contentType hanya informasi. Browser akan menggunakannya jika bisa, tetapi dalam hal ini browser hanya mengabaikannya karena mereka biasanya tidak tahu apa maksudnya. Aplikasi Javascript Anda dapat memanfaatkannya. Anda mengasumsikan bahwa JSON akan disajikan, sehingga Anda dapat mendekodekannya JSON.parse(). Anda bisa mengambil beberapa tindakan berbeda, atau memaksakan kesalahan jika tipe konten yang salah muncul.
1
Browser tidak secara otomatis mem-parsing teks JSON untuk Anda, jadi response.textmasih berupa string.
nnnnnn
1
Jadi, Anda bermaksud memberi tahu saya bahwa pengaturan tajuk itu tidak membuat perbedaan apa pun? Apa tujuan dari keberadaannya?
php_nub_qq
2
@php_nub_qq: Tujuannya adalah untuk memberi tahu Anda apa yang dikembalikan server sehingga aplikasi Anda dapat menanganinya. The Browser tidak akan mengurai JSON untuk Anda, aplikasi Anda perlu melakukan itu. Header ini memberi tahu Anda bahwa itu adalah (atau seharusnya JSON).
Rocket Hazmat

Jawaban:

136

The Content-Typeheader hanya digunakan sebagai informasi untuk aplikasi Anda. Peramban tidak peduli apa itu. Browser hanya mengembalikan Anda data dari panggilan AJAX. Jika Anda ingin menguraikannya sebagai JSON, Anda harus melakukannya sendiri.

Header ada di sana sehingga aplikasi Anda dapat mendeteksi data apa yang dikembalikan dan bagaimana penanganannya. Anda perlu melihat header, dan jika itu application/jsonparsing sebagai JSON.

Ini sebenarnya cara kerja jQuery. Jika Anda tidak memberi tahu apa yang harus dilakukan dengan hasilnya, ia menggunakan Content-Typeuntuk mendeteksi apa yang harus dilakukan dengan hasilnya.

Roket Hazmat
sumber
12
Itu tidak sepenuhnya benar. Jika Anda tidak menggunakan header('Content-Type: application/json');dan memaksa unduhan Content-Disposition: attachment; filename=myfile.jsonsaat itu, Anda akan berakhir dengan myfile.json.html. Dengan menggunakan json header ini, Anda akan mendapatkannya myfile.json.
Remi Grumeau
4
@RemiGrumeau Apa itu 'tidak sepenuhnya benar'? Mengunduh file dengan browser adalah sesuatu yang sangat berbeda. Peramban mungkin akan default untuk mengharapkan HTML, sehingga mengasumsikan apa pun yang diterimanya adalah HTML kecuali ditentukan lain. Saat mengunduh, itu ditambahkan .htmlke file, karena itu adalah defaultnya.
bzeaman
2
Saya tidak tahu konteks lengkap masalahnya di sini - TETAPI, browser (dan javascript) terkadang peduli dengan Tipe-Konten. Header ini dapat memengaruhi heuristik yang digunakan browser untuk menampilkan konten, dan mengirim XML dan JSON dengan tipe konten teks / html sering dapat membuat bug halus dalam permintaan XHR yang mendasarinya (atau lapisan kerangka kerja Anda di atas itu)
Alan Storm
7

Content-Type: application/jsonhanya header konten. Header konten hanyalah informasi tentang jenis data yang dikembalikan, ex :: JSON, gambar (png, jpg, dll.), Html.

Perlu diingat, bahwa JSON dalam JavaScript adalah array atau objek. Jika Anda ingin melihat semua data, gunakan console.log alih-alih lansiran:

alert(response.text); // Will alert "[object Object]" string
console.log(response.text); // Will log all data objects

Jika Anda ingin mengingatkan konten JSON asli sebagai string, tambahkan tanda kutip tunggal ('):

echo "'" . json_encode(array('text' => 'omrele')) . "'";
// alert(response.text) will alert {"text":"omrele"}

Jangan gunakan tanda kutip ganda. Ini akan membingungkan JavaScript, karena JSON menggunakan tanda kutip ganda pada setiap nilai dan kunci:

echo '<script>var returndata=';
echo '"' . json_encode(array('text' => 'omrele')) . '"';
echo ';</script>';

// It will return the wrong JavaScript code:
<script>var returndata="{"text":"omrele"}";</script>
Di antara Amrul
sumber
Tidak pernah melakukan hal ini, akan merusak pada setiap string menggunakan tanda kutip tunggal (dan itu sering terjadi di banyak bahasa): echo "'" . json_encode(array('text' => 'it\'s wrong')) . "'"; akan menghasilkan output ini rusak: '{"text":"it's wrong"}'. Gunakan ini sebagai gantinya: json_encode(json_encode(array('text' => 'it\'s good'))). Hasil akan lolos dengan benar:"{\"text\":\"it's wrong\"}"
PofMagicfingers
1

Kode di bawah ini membantu saya mengembalikan objek JSON untuk JavaScript di ujung depan

Kode templat saya

template_file.json

{
    "name": "{{name}}"
}

Kode yang didukung python

def download_json(request):
    print("Downloading JSON")
    # Response render a template as JSON object
    return HttpResponse(render_to_response("template_file.json",dict(name="Alex Vera")),content_type="application/json")    

File url.py

url(r'^download_as_json/$', views.download_json, name='download_json-url')

kode jQuery untuk ujung depan

  $.ajax({
        url:'{% url 'download_json-url' %}'        
    }).done(function(data){
        console.log('json ', data);
        console.log('Name', data.name);
        alert('hello ' + data.name);
    });
Alex Vera
sumber