Escape de JSON
El escape de JSON reescribe los caracteres que, de otro modo, terminarían o corromperían una cadena. RFC 8259 hace obligatorios dos escapes — " y \ — y añade después cinco escapes de control con nombre, un escape opcional para la barra inclinada y la forma universal \uXXXX. Esta guía cubre cada escape, los pares sustitutos que hay detrás de los emoji y cuándo el escape ayuda y cuándo estorba.
Escape de JSON: explicación
Cada cadena de JSON vive entre dos comillas dobles, así que el formato necesita una forma de poner una comilla doble dentro de una cadena sin terminarla — y una forma de poner una barra invertida dentro de una cadena sin iniciar un escape que nunca se quiso. La respuesta es el escape: una barra invertida colocada delante de un carácter cambia el significado de ese carácter para el analizador y convierte una marca estructural en datos corrientes.
El esquema es pequeño y cerrado. RFC 8259 define exactamente nueve escapes de dos caracteres más una forma extensible, \uXXXX, y nada más: una barra invertida seguida de cualquier otro carácter es un error de sintaxis, no un paso indulgente. Ese cierre es una virtud — los errores de escape siempre son reproducibles, porque un analizador conforme o reconoce la secuencia o rechaza el documento.
Esta guía recorre la tabla completa de escapes y después las dos partes que la gente encuentra más difíciles: \uXXXX y los pares sustitutos que necesita para los emoji, y el compromiso de tamaño de escapar texto no ASCII. Todos los ejemplos son copiables, y las herramientas enlazadas se ejecutan en tu navegador, así que puedes hacer idas y vueltas con tus propias cadenas localmente sin instalar nada.
La manera más rápida de ver el escape en acción es observar a un analizador resolverlo — el formateador de JSON muestra el resultado sin escapar junto a tu entrada mientras reindenta un documento.
El escape es un capítulo de la gramática; la la hoja de trucos de sintaxis JSON condensa el resto de las reglas — estructura, espacios en blanco, números — en una sola página de referencia.
Los dos escapes que nunca puedes saltarte
Dentro de una cadena, una comilla doble literal debe escribirse como " y una barra invertida literal como \\. Estos dos son obligatorios para todo generador, porque sin ellos un analizador no puede saber dónde termina una cadena ni dónde empieza un escape — no existe una grafía alternativa. Todos los demás escapes de la gramática son opcionales en el sentido de que su carácter podría haberse escrito literalmente; estos dos no tienen forma literal dentro de una cadena.
La barra diagonal es el caso especial: \/ es legal y significa /, pero la barra literal nunca necesita escaparse. La abreviatura existe por una razón histórica — incrustar JSON dentro de bloques <script> de HTML, donde la secuencia </script> dentro de una cadena podría cerrar antes de tiempo la etiqueta que la rodea. Algunos generadores todavía escapan todas las barras por precaución; el coste es un documento algo más grande y algo más ruidoso.
Escapes obligatorios y opcionales en un documento
{
"path": "C:\\temp\\notes.txt",
"line": "she said \"ship it\"",
"html": "<\\/script>"
}Lo que entrega un analizador
path: C:\temp\notes.txt line: she said "ship it" html: </script>
Los cinco caracteres de control con nombre
Un texto puede contener legalmente caracteres de control por debajo de U+0020 — tabulador, salto de línea, retorno de carro y compañía — pero un carácter de control en crudo dentro de una cadena JSON no es interoperable: rompe las herramientas basadas en líneas y a algunos analizadores directamente. Por eso el estándar exige escapar los caracteres de control y pone nombre a cinco: \b retroceso (U+0008), \f alimentación de formulario (U+000C), \n salto de línea (U+000A), \r retorno de carro (U+000D) y \t tabulador horizontal (U+0009). Cualquier otro carácter de control debe tomar la forma \u00XX, como \u0001.
Fíjate en lo que esto significa para los saltos de línea en particular: un documento con formato bonito tiene saltos de línea reales entre tokens, pero un salto de línea dentro de un valor de cadena son siempre los dos caracteres \n. Un valor de cadena ocupa una sola línea en el archivo incluso cuando su contenido tiene varias líneas — uno de los puntos de confusión más habituales al leer JSON formateado.
| Escape | Punto de código | Carácter |
|---|---|---|
| \b | U+0008 | retroceso |
| \t | U+0009 | tabulador horizontal |
| \n | U+000A | salto de línea |
| \f | U+000C | alimentación de formulario |
| \r | U+000D | retorno de carro |
| \u00XX | U+0000–U+001F | cualquier otro carácter de control |
Una nota de tres líneas guardada en una cadena JSON
{
"note": "first line\nsecond line\ttabbed"
}Su contenido tras el análisis
first line second line tabbed
\uXXXX: cualquier punto de código, exactamente cuatro dígitos hexadecimales
El escape \u escribe un punto de código como exactamente cuatro dígitos hexadecimales: \u00e9 es é, \u4f60 es 你, \u0041 es la misma A que podrías haber tecleado literalmente. Los analizadores tratan la forma escapada y la literal como idénticas — un documento que escapa cada carácter no ASCII y otro que no escapa nada salvo los dos obligatorios se descodifican en exactamente las mismas cadenas. Escapar es una decisión de transporte, no una diferencia de datos.
Los cuatro dígitos limitan la forma a puntos de código hasta U+FFFF, el Plano Multilingüe Básico. Todo lo que está por encima — emoji, escrituras históricas, la mayoría de los símbolos — no cabe en un solo escape \u, y esa limitación es exactamente donde entran en escena los pares sustitutos.
Dos grafías del mismo valor
{
"city": "\u5317\u4eac",
"note": "escaped form"
}
{
"city": "北京",
"note": "literal UTF-8"
}Ambas se analizan en la misma cadena
city: 北京 (el archivo escapado es solo ASCII; el literal es más pequeño, pero multibyte)
Plano astral: pares sustitutos y sustitutos huérfanos
Internamente, JavaScript y la notación \u trabajan en unidades de código UTF-16. Los caracteres por encima de U+FFFF se escriben como una pareja: un sustituto alto de U+D800–U+DBFF seguido de un sustituto bajo de U+DC00–U+DFFF. La carita sonriente U+1F600 se convierte por tanto en \ud83d\ude00 — doce caracteres de origen para un solo emoji. Escapa una mitad sin la otra y tienes un sustituto huérfano: RFC 8259 §8.2 marca esas cadenas como impredecibles de interpretar, y los generadores interoperables simplemente nunca las emiten.
Los pares sustitutos son también la razón por la que la longitud de una cadena miente. JavaScript informa de que la longitud de "😀" es 2, porque cuenta unidades de código UTF-16 en lugar de caracteres — un detalle que importa cuando cortas, truncas o validas texto escapado, y la razón de que existan bibliotecas conscientes de los grafemas.
Un emoji, dos unidades de código, doce caracteres escapados
{
"mood": "\ud83d\ude00"
}
{
"mood": "😀"
}Ambas se analizan en el mismo carácter único
mood: 😀 (U+1F600 — length 2 in UTF-16 units)
El coste del escape: legibilidad y tamaño
Escapar cambia legibilidad por seguridad. Un documento que escapa cada carácter no ASCII sobrevive a cualquier canal de 7 bits — pasarelas que eliminan el octavo bit de cada byte, sistemas de correo antiguos, registros configurados como ASCII puro — al precio de ser casi ilegible para los humanos. Esa era la postura predeterminada de muchas bibliotecas JSON antiguas; los valores predeterminados modernos prefieren UTF-8 literal y escapan solo lo que la gramática exige.
El coste de tamaño es predecible a partir del punto de código, porque cada escape \uXXXX cuesta exactamente 6 bytes sin importar lo que codifique. Quitar los escapes a un documento cargado de CJK lo reduce aproximadamente a la mitad; el texto árabe y cirílico se encoge unos dos tercios; y escapar ASCII puro lo multiplica por seis — razón por la que las cargas útiles escapadas en ASCII de sistemas antiguos parecen mucho más gordas que su contenido real.
| Texto | Punto de código | UTF-8 literal | Forma escapada | Tamaño escapado |
|---|---|---|---|---|
| a | U+0061 | 1 byte | \u0061 | 6 bytes |
| ب | U+0628 | 2 bytes | \u0628 | 6 bytes |
| а | U+0430 | 2 bytes | \u0430 | 6 bytes |
| 你 | U+4F60 | 3 bytes | \u4f60 | 6 bytes |
| 😀 | U+1F600 | 4 bytes | \ud83d\ude00 | 12 bytes |
Quitar escapes, idas y vueltas y cuándo conservarlos
Quitar los escapes no es una operación aparte que tengas que escribir: todo analizador conforme la realiza durante la descodificación, así que analizar "\u0041" y analizar "A" produce cadenas idénticas. La dirección inversa — decidir qué escapar al generar JSON — es donde las bibliotecas difieren en gustos, y donde las únicas reglas duras son los dos escapes obligatorios más el requisito de los caracteres de control.
Reserva el escape agresivo para sus dos casos de uso honestos: sobrevivir a canales en los que no se puede confiar con UTF-8, y los diffs donde cada diferencia de codificación invisible debería hacerse visible. En cualquier otro lugar, el UTF-8 literal con escapes mínimos es más pequeño, más rápido de ojear y más fácil de revisar. Si un documento recibido parece sobre-escapado, analízalo y re-serialízalo una vez — la salida elimina cada escape opcional y sigue siendo exactamente los mismos datos.
Preguntas frecuentes
¿Es seguro pegar cadenas sensibles en las herramientas JSON de este sitio?
Sí — el formateador, el validador y el minificador enlazados desde esta guía se ejecutan localmente en tu navegador. No hay paso de subida: el análisis y la re-serialización ocurren en JavaScript dentro de la pestaña, el panel «Network» no muestra ninguna petición que lleve tu texto, y la Content-Security-Policy del sitio bloquea las conexiones salientes como segunda línea de defensa. Tus cadenas nunca salen de la máquina donde las tecleaste.
¿Cómo pongo un emoji en una cadena JSON?
De dos maneras: pega el emoji literalmente — 😀 es JSON UTF-8 válido — o escribe su par sustituto, \ud83d\ude00. Ambas se descodifican en el mismo carácter. Conviene conocer la forma escapada porque algunos canales y herramientas antiguas estropean los emoji literales, y porque los mensajes de error, los registros y los diffs a menudo te muestran el par en lugar de la carita.
¿Qué es un sustituto huérfano y por qué rompe los analizadores?
Un sustituto alto (\ud800–\udbff) o bajo (\udc00–\udfff) escrito sin su pareja. Solo no codifica nada: RFC 8259 §8.2 llama a las cadenas que los contienen impredecibles de interpretar. Las implementaciones varían — algunas los aceptan, otras los sustituyen por U+FFFD, otras lanzan un error — así que nunca emitas media pareja y trata un sustituto huérfano en los datos entrantes como una corrupción.
¿Por qué \/ es un escape válido si / no necesita escaparse?
Existe para incrustar JSON en HTML: dentro de un bloque <script>, la secuencia literal </script> en una cadena terminaría el bloque antes de tiempo, así que los generadores escapan cada barra como \/ para romper el patrón. La gramática acepta igualmente la forma sin escapar. Salvo que estés incrustando JSON en HTML, \/ es ruido puro — y los minificadores lo eliminan encantados.
¿El escape cambia los datos que recibe mi API?
No. Los escapes son grafías, no valores: "\u00e9" y "é" se descodifican en la cadena idéntica, así que cualquier analizador conforme entrega el mismo texto Unicode de cualquier manera. Escapar cambia solo el aspecto del archivo y su tamaño — por eso una respuesta sobre-escapada es fea pero inofensiva, y por eso puedes normalizarla analizando y re-serializando.
¿Cuánto más pequeño es el JSON sin los escapes \u?
Depende de la escritura, porque cada \uXXXX cuesta 6 bytes mientras que el UTF-8 literal cuesta 1 byte para ASCII, 2 para letras árabes o cirílicas, 3 para CJK y 4 para emoji. Quitar los escapes a un documento chino lo reduce más o menos a la mitad; el árabe o el cirílico se encoge unos dos tercios; escapar ASCII lo multiplica por seis. La forma escapada es siempre igual o más grande.
¿Dónde puedo leer las normas citadas aquí?
- RFC 8259 — El formato de intercambio de datos JavaScript Object Notation (JSON)
¿Qué herramientas relacionadas debería usar después?
- Formatear JSONIndenta, ordena claves y quita comentariosAbrir
- Hoja de trucos de sintaxis JSONGuía en lenguaje sencilloAbrir
- Qué es JSONGuía en lenguaje sencilloAbrir
- Minificar JSONQuita espacios y mide el tamaño real en gzipAbrir
- Validar JSONValida la sintaxis con línea y columna exactas y repara los erroresAbrir
- Herramientas de codificaciónBase64, codificación de URL, hashes e inspección de tokens.Abrir