Заголовок типу вмісту HTTP та JSON


144

Я завжди намагався уникати використання більшості властивостей протоколу HTTP заради страху перед невідомим.

Однак я сказав собі, що сьогодні зіткнуся зі страхом і почну цілеспрямовано використовувати заголовки. Я намагаюся надсилати jsonдані в браузер і використовувати їх відразу. Наприклад, якщо у мене функція обробника Ajax у стані готового 4, це виглядає так:

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

І я встановив заголовок типу вмісту у своєму PHP-коді:

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

Чому я не можу отримати прямий доступ до ресурсу за допомогою функції обробника, коли в браузері чітко сказано, що вхідні дані є application/json?


Якщо я правильно розумію, ви хочете використовувати textяк змінну javascript у обробнику, а не відповідь? Це було б дуже дивно. Код json_en також створює 1 об’єкт із масиву PHP. Отже, коли ви отримуєте це в javascript, його потрібно призначити змінною.
Flashin

4
Заголовок contentType є лише інформаційним. Веб-браузер використовуватиме це, якщо може, але в цьому випадку браузери просто ігнорують його, оскільки вони зазвичай не знають, що таке ціль. Ваша програма Javascript може використовувати її. Ви припускаєте, що буде представлений JSON, тож ви можете його розшифрувати JSON.parse(). Ви можете вжити деяких інших дій або виправити помилку, якщо з'явиться неправильний contentType

1
Веб-переглядач не автоматично розбирає текст JSON для вас, тому response.textце все ще є рядком.
nnnnnn

1
Отже, ти маєш на увазі сказати мені, що налаштування цього заголовка не має ніякої різниці в чомусь колись? Яка мета його існування тоді?
php_nub_qq

2
@php_nub_qq: Його мета - сказати вам, що повернувся сервер, щоб ваша програма могла відповідно обробляти це. Веб- переглядач не розбере JSON для вас, ваш додаток повинен це зробити. Цей заголовок говорить про те, що це (або повинен бути JSON).
Ракета Hazmat

Відповіді:


136

Content-TypeТема використовуються тільки в якості інформації для вашого застосування. Браузер байдуже, що це таке. Браузер просто повертає вам дані з виклику AJAX. Якщо ви хочете розібрати його як JSON, вам потрібно зробити це самостійно.

Заголовок є, щоб ваша програма могла визначити, які дані були повернуті та як вона повинна обробляти їх. Потрібно подивитися на заголовок, і якщо він application/jsonпотім розбере його як JSON.

Це насправді, як працює jQuery. Якщо ви не скажете йому, що робити з результатом, він використовує функцію Content-Typeвиявлення, що з цим робити.


12
Це не зовсім вірно. Якщо ви не скористаєтеся header('Content-Type: application/json');і не завантажуєте її до Content-Disposition: attachment; filename=myfile.jsonцього часу, тоді ви отримаєте myfile.json.html. Використовуючи цей заголовок json, ви отримаєте myfile.json.
Ремі Грумеу

4
@RemiGrumeau Що таке "не зовсім правда"? Завантаження файлів за допомогою браузера - це зовсім інше. Браузер, ймовірно, за замовчуванням очікує HTML, тому він передбачає, що все, що він отримує, це HTML, якщо інше не вказано. Під час завантаження додається .htmlдо файлу, тому що для цього він за замовчуванням.
bzeaman

2
Я не знаю тут повного контексту проблеми - АЛЕ браузери (та JavaScript) інколи дбають про Content-Type. Цей заголовок може впливати на евристику, яку браузер використовує для відображення вмісту, а надсилання XML та JSON із текстом / html-вмістом типу вмісту часто може створювати непомітні помилки в основоположних запитах XHR (або шарах вашої рамки поверх них)
Alan Storm

7

Content-Type: application/json- це лише заголовок вмісту. Заголовок вмісту - це лише інформація про тип повернених даних, наприклад: JSON, image (png, jpg тощо), html.

Майте на увазі, що JSON у JavaScript - це масив чи об’єкт. Якщо ви хочете переглянути всі дані, використовуйте console.log замість попередження:

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

Якщо ви хочете попередити оригінальний вміст JSON як рядок, додайте окремі лапки ('):

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

Не використовуйте подвійні лапки. Це заплутає JavaScript, оскільки JSON використовує подвійні лапки на кожне значення та ключ:

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>

Ніколи не робіть цього, він зламається на будь-якому рядку , використовуючи одиничні лапки (і це часто в різних мовах): echo "'" . json_encode(array('text' => 'it\'s wrong')) . "'"; буде виробляти цей зламаний висновок: '{"text":"it's wrong"}'. Натомість використовуйте: json_encode(json_encode(array('text' => 'it\'s good'))). Результат буде досягнуто правильно:"{\"text\":\"it's wrong\"}"
PofMagicfingers

1

Наведений нижче код допомагає мені повернути об’єкт JSON для JavaScript на передній частині

Код мого шаблону

template_file.json

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

Підтримуваний 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")    

Файл url.py

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

Код jQuery для переднього кінця

  $.ajax({
        url:'{% url 'download_json-url' %}'        
    }).done(function(data){
        console.log('json ', data);
        console.log('Name', data.name);
        alert('hello ' + data.name);
    });
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.