【问题标题】:HTTP Content-Type Header and JSONHTTP 内容类型标头和 JSON
【发布时间】:2022-05-02 07:45:31
【问题描述】:

出于对未知的恐惧,我一直试图避免使用 HTTP 协议的大部分属性。

但是,我对自己说,我今天要面对恐惧,开始有目的地使用标题。我一直在尝试将json 数据发送到浏览器并立即使用它。例如,如果我有一个处于就绪状态 4 的 Ajax 处理函数,看起来像这样:

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

我已经在我的 PHP 代码中设置了 content-type 标头:

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

当浏览器被明确告知传入的数据是application/json时,为什么我不能直接从处理函数访问属性?

【问题讨论】:

  • 如果我理解正确,您想在处理程序中使用text 作为javascript 变量而不是响应?那将是非常奇怪的功能。 json_encode 还会从您的 PHP 数组中创建 1 个对象。因此,当您将其放入 javascript 中时,需要将其分配给一个变量。
  • contentType 标头仅供参考。如果可以,浏览器会使用它,但在这种情况下,浏览器会简单地忽略它,因为它们通常不知道意图是什么。您的 Javascript 应用程序可以使用它。您假设将显示 JSON,因此您可以使用 JSON.parse() 对其进行解码。如果出现错误的 contentType,您可以采取一些不同的操作,或者强制出错。
  • 浏览器不会自动为你解析JSON文本,所以response.text仍然是一个字符串。
  • 所以你的意思是告诉我设置该标题没有任何区别?那么它存在的目的是什么?
  • @php_nub_qq:它的目的是告诉您服务器返回了什么,以便您的应用程序可以相应地处理它。 浏览器 不会为您解析 JSON,您的应用需要这样做。此标头告诉您它是(或应该是 JSON)。

标签: javascript php json http http-headers


【解决方案1】:

Content-Type 标头仅用作您的应用程序的信息。浏览器不在乎它是什么。浏览器只是返回来自 AJAX 调用的数据。如果你想把它解析为 JSON,你需要自己做。

标头在那里,因此您的应用可以检测返回的数据以及应如何处理这些数据。您需要查看标头,如果是 application/json 则将其解析为 JSON。

这实际上是 jQuery 的工作方式。如果你不告诉它如何处理结果,它会使用Content-Type 来检测如何处理它。

【讨论】:

  • 这并不完全正确。如果您不使用header('Content-Type: application/json'); 并通过Content-Disposition: attachment; filename=myfile.json 强制下载,那么您最终会得到myfile.json.html。使用此 json 标头,您将获得 myfile.json
  • @RemiGrumeau 什么是“不完全正确”?用浏览器下载文件是完全不同的。浏览器可能会默认期待 HTML,因此除非另有说明,否则它假定它接收到的任何内容都是 HTML。下载时,它会将.html 附加到文件中,因为这是它的默认值。
  • 我不知道这里问题的完整背景——但是,浏览器(和 javascript)有时确实关心 Content-Type。此标头可能会影响浏览器用于显示内容的启发式方法,并且发送内容类型为 text/html 的 XML 和 JSON 通常会在底层 XHR 请求(或框架之上的层)中产生细微的错误
  • 当我有页面生成 JSON 数据时,我会放置此标头。因为在 Mozilla Firefox 下,例如没有标题,数据没有被格式化,而有标题,它被格式化并且非常可读。
【解决方案2】:

Content-Type: application/json 只是内容标题。内容头只是关于返回数据类型的信息,例如::JSON,image(png,jpg,etc..),html。

请记住,JavaScript 中的 JSON 是一个数组或对象。如果您想查看所有数据,请使用 console.log 而不是 alert:

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' =&gt; 'it\'s wrong')) . "'"; 将产生这个损坏的输出:'{"text":"it's wrong"}'。改用这个:json_encode(json_encode(array('text' =&gt; 'it\'s good')))。结果将被正确转义:"{\"text\":\"it's wrong\"}"
【解决方案3】:

这很旧,但对我来说 PHP8 如果设置了字符集示例,它就可以工作。

header('Content-Type: application/json; charset=utf-8');
echo json_encode(array('text' => 'eggs'));

【讨论】:

    【解决方案4】:

    下面的代码帮助我在前端为 JavaScript 返回一个 JSON 对象

    我的模板代码

    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);
        });
    

    【讨论】:

      【解决方案5】:

      最近遇到了一个问题,当响应标头将内容类型标记为“text/html”时,Chrome 扩展程序损坏了 JSON 流。

      显然扩展可以并且将会在浏览器处理它之前使用响应头来改变内容。

      更改内容类型解决了问题。

      【讨论】:

        猜你喜欢
        • 2016-04-17
        • 2011-09-30
        • 2013-10-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-30
        • 2013-12-11
        • 2016-01-01
        相关资源
        最近更新 更多