tutorial ¿Cuál es el tipo de contenido JSON correcto?




json tutorial (24)

Extendiendo las respuestas aceptadas, cuando está utilizando JSON en un contexto REST ...

Existe un fuerte argumento sobre el uso de application/x-resource+json y application/x-collection+json cuando se representan recursos y colecciones REST.

Y si decide seguir la especificación jsonapi , debe usar application/vnd.api+json , tal como está documentado.

Si bien no existe un estándar universal, está claro que la semántica agregada a los recursos que se transfieren justifica un tipo de contenido más explícito que solo application/json .

Siguiendo este razonamiento, otros contextos podrían justificar un tipo de contenido más específico.

He estado jugando con JSON por algún tiempo, solo lo puse como texto y no ha afectado a nadie (que yo sepa), pero me gustaría empezar a hacer las cosas correctamente.

He visto tantos supuestos "estándares" para el tipo de contenido JSON:

application/json
application/x-javascript
text/javascript
text/x-javascript
text/x-json

¿Pero cuál es correcto, o mejor? Entiendo que hay problemas de seguridad y soporte de navegador que varían entre ellos.

Sé que hay una pregunta similar, ¿Qué tipo de MIME si JSON está siendo devuelto por una API REST? , pero me gustaría una respuesta un poco más específica.


Como muchos otros han mencionado, application/json es la respuesta correcta.

Pero lo que aún no se ha explicado es qué significan las otras opciones que propuso.

  • application/x-javascript : tipo MIME experimental para JavaScript antes de que application/javascript estándar.

  • text/javascript : ahora obsoleto. Debes usar application/javascript cuando uses javascript.

  • text/x-javascript : tipo MIME experimental para la situación anterior.

  • text/x-json : tipo MIME experimental para JSON antes de que la application/json se registrara oficialmente.

En definitiva, siempre que tenga dudas sobre los tipos de contenido, debe consultar este enlace.


JSON es un lenguaje específico de dominio (DSL) y un formato de datos independiente de JavaScript, y como tal tiene su propio tipo MIME , application/json . Por supuesto, el respeto por los tipos MIME está impulsado por el cliente, por lo que se puede hacer text/plain para la transferencia de bytes, pero entonces sería innecesario aumentar la interpretación al dominio de la aplicación del proveedor innecesariamente - application/json . ¿Transferirías XML vía text/plain ?

Pero honestamente, su elección del tipo MIME es un consejo para el cliente sobre cómo interpretar los datos- text/plain o text/HTML (cuando no es HTML) es como borrar el tipo, es tan poco informativo como hacer que todos sus objetos de tipo objeto en un lenguaje mecanografiado.

No sé, el tiempo de ejecución del navegador tomará un documento JSON y lo pondrá a disposición automáticamente como un objeto accesible de JavaScript sin intervención, pero si está trabajando con un cliente paralizado, es un asunto completamente diferente. Pero esa no es toda la historia: los RESTful JSON a menudo no tienen tiempos de ejecución de JavaScript, pero no les impide utilizar JSON como un formato de intercambio de datos viable. Si los clientes están tan lisiados ... entonces consideraría quizás la inyección de HTML a través de un servicio de plantillas Ajax .

Aplicación / JSON!


El tipo de contenido correcto para JSON es application/json MENOS que esté usando JSONP , también conocido como JSON con Padding, que en realidad es JavaScript y, por lo tanto, el tipo de contenido correcto sería application/javascript .


Solo cuando uso application/json como tipo MIME tengo lo siguiente (a partir de noviembre de 2011 con las versiones más recientes de Chrome, Firefox con Firebug ):

  • No hay más advertencias de Chrome cuando el JSON se carga desde el servidor.
  • Firebug agregará una pestaña a la respuesta que muestra los datos JSON formateados. Si el tipo MIME es diferente, solo aparecerá como "Contenido de respuesta".

JSON:

La respuesta es datos generados dinámicamente, de acuerdo con los parámetros de consulta pasados ​​en la URL.

Ejemplo:

{ "Name": "Foo", "Id": 1234, "Rank": 7 }

Tipo de contenido: application/json

JSON-P:

JSON con relleno. La respuesta son datos JSON, con una llamada de función envuelta alrededor de ellos.

Ejemplo:

functionCall({"Name": "Foo", "Id": 1234, "Rank": 7});

Tipo de contenido: application/javascript


" application/json " es el tipo de contenido JSON correcto.

def ajaxFindSystems = {
  def result = Systems.list()
  render(contentType:'application/json') {
    results {
      result.each{sys->
        system(id:sys.id, name:sys.name)
      }
    }
    resultset (rows:result.size())
  }
}

No hay duda de que application/json es el mejor tipo MIME para una respuesta JSON.

Pero tenía alguna experiencia en la que tenía que usar application/x-javascript debido a algunos problemas de compresión. Mi entorno de hosting es hosting compartido con GoDaddy . No me permiten cambiar las configuraciones del servidor. Había añadido el siguiente código a mi archivo web.config para comprimir las respuestas.

<httpCompression>
    <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll"/>
    <dynamicTypes>
        <add mimeType="text/*" enabled="true"/>
        <add mimeType="message/*" enabled="true"/>
        <add mimeType="application/javascript" enabled="true"/>
        <add mimeType="*/*" enabled="false"/>
    </dynamicTypes>
    <staticTypes>
        <add mimeType="text/*" enabled="true"/>
        <add mimeType="message/*" enabled="true"/>
        <add mimeType="application/javascript" enabled="true"/>
        <add mimeType="*/*" enabled="false"/>
    </staticTypes>
</httpCompression>
<urlCompression doStaticCompression="true" doDynamicCompression="true"/>

Al usar esto, las páginas .aspx se comprimieron con g-zip pero las respuestas JSON no. yo añadí

<add mimeType="application/json" enabled="true"/>

En las secciones de tipos estáticos y dinámicos. Pero esto no comprime las respuestas JSON en absoluto.

Después de que quité este tipo recién agregado y agregué

<add mimeType="application/x-javascript" enabled="true"/>

en las secciones de tipos estáticos y dinámicos, y cambió el tipo de respuesta en

.ashx (controlador asíncrono) a

application/x-javascript

Y ahora descubrí que mis respuestas JSON estaban comprimidas con g-zip. Así que personalmente recomiendo usar

application/x-javascript

solo si desea comprimir sus respuestas JSON en un entorno de alojamiento compartido . Porque en el alojamiento compartido, no le permiten cambiar las configuraciones de IIS .


Si está utilizando Ubuntu o Debian y sirve archivos .json a través de Apache, es posible que desee servir los archivos con el tipo de contenido correcto. Estoy haciendo esto principalmente porque quiero usar la extensión JSONView Firefox

El módulo Apache mod_mime ayudará a hacer esto fácilmente. Sin embargo, con Ubuntu necesita editar el archivo /etc/mime.types y agregar la línea

application/json json

Luego reinicie Apache:

sudo service apache2 restart

El registro de la IANA para la application/json dice

Aplicaciones que utilizan este tipo de medio: JSON se ha utilizado para intercambiar datos entre aplicaciones escritas en todos estos lenguajes de programación: ActionScript, C, C #, Clojure, ColdFusion, Common Lisp, E, Erlang, Go, Java, JavaScript, Lua, Objective CAML, Perl, PHP, Python, Rebol, Ruby, Scala y Scheme.

Notará que IANA.org no lista ninguno de estos otros tipos de medios , de hecho, incluso la application/javascript ahora está obsoleta. Entonces application/json es realmente la única respuesta correcta posible.

El soporte del navegador es otra cosa.

Los tipos de medios no estándar más compatibles son text/json o text/javascript . Pero algunos nombres grandes incluso usan text/plain .

Aún más extraño es el encabezado Content-Type enviado por Flickr, que devuelve JSON como text/xml . Google usa text/javascript para algunas de sus apis de ajax.

Ejemplos:

curl -I "https://ajax.googleapis.com/ajax/services/search/video?v=1.0&q=jsonexample"

Salida: Content-Type: text/javascript

curl -I "https://www.flickr.com/services/rest/?method=flickr.test.echo&format=json&api_key=f82254c1491d894f1204d8408f645a93"

Salida: Content-Type: text/xml


Para texto JSON:

application/json

El tipo de medio MIME para texto JSON es application/json . La codificación predeterminada es UTF-8. (Fuente: RFC 4627 ).

Para JSONP (javascript ejecutable) con devolución de llamada:

application/javascript

Aquí hay algunas publicaciones de blog que fueron mencionadas en los comentarios que son relevantes.


Si obtiene datos de la API REST en JSON, debe usar el tipo de contenido

For JSON data: Content-Type:application/json
For HTML data: Content-Type:text/html,
For XHTML data: Content-Type:application/xhtml+xml,
For XML data: Content-Type:text/xml, application/xml

El tipo MIME correcto es application/json

PERO

Experimenté muchas situaciones donde el tipo de navegador o el usuario del framework necesitaban:

text/html

application/javascript

Por supuesto, el tipo de medio MIME correcto para JSON es application/json , pero es necesario darse cuenta del tipo de datos que se esperan en su aplicación.

Por ejemplo, uso Ext GWT y la respuesta del servidor debe ir como texto / html pero contiene datos JSON.

Lado del cliente, oyente de forma Ext GWT

uploadForm.getForm().addListener(new FormListenerAdapter()
{
    @Override
    public void onActionFailed(Form form, int httpStatus, String responseText) 
    {
        MessageBox.alert("Error");
    }

    @Override
    public void onActionComplete(Form form, int httpStatus, String responseText) 
    {
        MessageBox.alert("Success");
    }
});

En caso de usar el tipo de respuesta application / json , el navegador me sugiere guardar el archivo.

Fragmento de código fuente del lado del servidor usando Spring MVC

return new AbstractUrlBasedView() 
{
    @SuppressWarnings("unchecked")
    @Override
    protected void renderMergedOutputModel(Map model, HttpServletRequest request,
                                           HttpServletResponse response) throws Exception 
    {
        response.setContentType("text/html");
        response.getWriter().write(json);
    }
};


Para JSON:

Content-Type: application/json

Para JSONP :

Content-Type: application/javascript

JSON formatos JSON (Notación de objetos de JavaScript) y JSONP ("JSON con relleno") parecen ser muy similares y, por lo tanto, podría ser muy confuso qué tipo de MIME deberían estar usando. Aunque los formatos parecen ser muy similares, hay algunas diferencias sutiles entre ellos.

Entonces, cuando tenga dudas, tengo un enfoque muy simple (que funciona perfectamente en la mayoría de los casos), es decir, vaya y verifique el documento RFC correspondiente.

JSON RFC 4627 (La aplicación / json Media Type para JavaScript Object Notation (JSON)) es una especificación del formato JSON. Dice en la sección 6, que el tipo de medio MIME para texto JSON es

application/json.

JSONP JSONP ("JSON con relleno") se maneja de manera diferente a JSON, en un navegador. JSONP se trata como un script de JavaScript normal y, por lo tanto, debe usar application/javascript, el tipo MIME oficial actual para JavaScript. En muchos casos, sin embargo, el tipo MIME de text/javascript también funcionará bien.

Tenga en cuenta que el text/javascript ha sido marcado como obsoleto por el documento rfc-editor.org/rfc/rfc4329.txt (Tipos de medios de scripting) y se recomienda usar el tipo de application/javascript lugar. Sin embargo, debido a razones heredadas, el text/javascript todavía se usa ampliamente y tiene compatibilidad con varios navegadores (lo que no siempre es un caso con el tipo MIME de la application/javascript , especialmente con los navegadores más antiguos).


Los desarrolladores de PHP usan esto:

<?php
    header("Content-type: application/json");

    // Do something here...
?>

No todo funciona para la application/json tipo de contenido application/json .

Si está utilizando el envío de formulario Ext JS para cargar un archivo, tenga en cuenta que el navegador analiza la respuesta del servidor para crear el documento para el <iframe> .

Si el servidor utiliza JSON para enviar el objeto de devolución, el encabezado Content-Type debe configurarse en text/html para indicar al navegador que inserte el texto sin modificar en el cuerpo del documento.

Consulte la documentación de la API Ext JS 3.4.0 .


Si el JSON está con relleno, será application/jsonp . Si el JSON está sin relleno, será application/json .

Para lidiar con ambos, es una buena práctica usar: 'aplicación / javascript' sin preocuparse de si es con relleno o sin relleno.


En JSP , puede usar esto en la directiva de página:

<%@ page language="java" contentType="application/json; charset=UTF-8"
    pageEncoding="UTF-8"%>

El tipo de medio MIME correcto para JSON es application/json . JSP lo usará para enviar una respuesta al cliente.


El encabezado Content-Type se debe establecer en ' application / json ' cuando se publique. El servidor que escucha la solicitud debe incluir " Aceptar = aplicación / json ". En Spring MVC puedes hacerlo así:

@RequestMapping(value="location", method = RequestMethod.POST, headers = "Accept=application/json")

Agregar encabezados a la respuesta:

HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json");

Yo uso el siguiente

contentType: 'application/json',
data: JSON.stringify(SendData),

En Spring tienes un tipo definido: MediaType.APPLICATION_JSON_VALUE que es equivalente a application / json .





content-type