# Como formatar e validar JSON em JavaScript, Python e PHP

> Formatar JSON é ler o texto e escrevê-lo de novo com quebras de linha e recuo. Validar é tentar ler e tratar o erro. Este guia mostra as duas coisas em JavaScript, Python e PHP, lista os erros que mais quebram um JSON e explica as diferenças que pegam de surpresa, como acentos escapados no PHP e NaN aceito no Python.

- Endereço oficial: https://pradev.com.br/guias/como-formatar-e-validar-json
- Tipo: Guia
- Publicado em: 2026-09-30
- Atualizado em: 2026-09-30
- Autor: Leonardo Gaertner (https://pradev.com.br/sobre)
- Ferramentas: [Formatador JSON](https://pradev.com.br/formatador-json), [Validador JSON](https://pradev.com.br/validador-json)

## Os erros que mais quebram um JSON

- Vírgula sobrando depois do último item: `{"a": 1,}`.
- Aspas simples em vez de duplas: `{'a': 1}`. O JSON só aceita aspas duplas.
- Chaves sem aspas: `{a: 1}`. Isso é objeto de JavaScript, não JSON.
- Valores que o JSON não tem: `undefined`, `NaN`, `Infinity`, comentários e datas sem aspas.

O [validador de JSON](https://pradev.com.br/validador-json) aponta a linha e a coluna do erro, e o [formatador de JSON](https://pradev.com.br/formatador-json) deixa o texto legível. Em código, o caminho é o mesmo: ler, tratar o erro e escrever de novo.

## Em JavaScript

O terceiro argumento de `JSON.stringify` define o recuo. A mensagem de erro do `JSON.parse` muda entre navegadores e versões do Node.js, então use-a para mostrar ao usuário, não para tomar decisões no código.

```javascript
function formatarJSON(texto, espacos = 2) {
  return JSON.stringify(JSON.parse(texto), null, espacos);
}

function validarJSON(texto) {
  try {
    JSON.parse(texto);
    return { valido: true };
  } catch (erro) {
    return { valido: false, mensagem: erro.message };
  }
}
```

_JavaScript_

## Em Python

O `json.loads` aceita `NaN` e `Infinity`, que não são JSON: o `parse_constant` recusa esses valores. Sem `ensure_ascii=False`, o `json.dumps` escreve `\u00e7` no lugar de `ç`. O erro traz a linha e a coluna.

```python
import json


def _recusar(nome):
    raise ValueError(f"{nome} não é JSON válido")


def formatar_json(texto: str, espacos: int = 2) -> str:
    # parse_constant: o Python aceitaria NaN e Infinity, que o JSON não permite
    dados = json.loads(texto, parse_constant=_recusar)
    return json.dumps(dados, indent=espacos, ensure_ascii=False)


def validar_json(texto: str) -> dict:
    try:
        json.loads(texto, parse_constant=_recusar)
        return {"valido": True}
    except json.JSONDecodeError as e:
        return {"valido": False, "mensagem": e.msg, "linha": e.lineno, "coluna": e.colno}
    except ValueError as e:
        return {"valido": False, "mensagem": str(e)}
```

_Python_

## Em PHP

Com `JSON_THROW_ON_ERROR`, o `json_decode` lança uma exceção em vez de devolver `null` em silêncio, o que evita confundir um JSON inválido com o valor `null`. O `JSON_PRETTY_PRINT` usa quatro espaços. No PHP 8.3 ou mais novo, `json_validate` confere sem montar os dados.

```php
<?php
function formatarJson(string $texto): string
{
    $dados = json_decode($texto, false, 512, JSON_THROW_ON_ERROR);
    // Sem as duas últimas opções, o PHP escreveria \u00e7 no lugar de ç
    // e \/ no lugar de /
    return json_encode(
        $dados,
        JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES
    );
}

function validarJson(string $texto): array
{
    try {
        json_decode($texto, false, 512, JSON_THROW_ON_ERROR);
        return ['valido' => true];
    } catch (JsonException $e) {
        return ['valido' => false, 'mensagem' => $e->getMessage()];
    }
}
```

_PHP_

## Diferenças entre as linguagens

- Números: o JavaScript escreve `1.0` como `1`, e o Python mantém `1.0`. Os dois são o mesmo número em JSON.
- Números grandes: no JavaScript, inteiros acima de 9007199254740991 perdem precisão no `JSON.parse`. IDs grandes devem trafegar como texto.
- Objeto vazio no PHP: com `json_decode($texto, true)`, o `{}` vira array vazio e volta como `[]`. Por isso o exemplo usa objetos (`false`).
- Ordem das chaves: as três linguagens mantêm a ordem do texto, mas o JSON não garante ordem. Não dependa dela.

## Perguntas frequentes

### Como formatar JSON em JavaScript?

Use JSON.stringify(JSON.parse(texto), null, 2). O último argumento é o número de espaços do recuo. Se o texto não for JSON válido, o JSON.parse lança um erro.

### JSON aceita comentários?

Não. Comentários, vírgula sobrando e aspas simples tornam o texto inválido. Alguns formatos derivados, como o JSONC usado em arquivos de configuração, aceitam comentários, mas não são JSON puro.

### Por que o PHP escreve \u00e7 no lugar de ç no JSON?

Por padrão, o json_encode escapa caracteres fora do ASCII. A opção JSON_UNESCAPED_UNICODE mantém os acentos. O resultado é equivalente, mas fica mais legível e menor.

### Como achar o erro em um JSON grande?

Use uma ferramenta que mostre a linha e a coluna, como o validador de JSON do PraDev, ou o json.loads do Python, que traz essas informações no erro.

## Fontes

- [RFC 8259: o formato JSON](https://www.rfc-editor.org/rfc/rfc8259)
- [Python: módulo json](https://docs.python.org/3/library/json.html)
