Loading

ROUTE

ルートゼロの
アクティビティ

JSON.parseのUnexpected tokenを切り分ける手順

2

JavaScriptのJSON.parseで「Unexpected token」などのSyntaxErrorが出たら、まず解析対象が本当にJSON文字列かを確認してください。原因は、末尾のカンマ、シングルクォート、キーのダブルクォート不足、空文字、APIから返ったHTMLなどに分かれます。API連携ならHTTPステータス・Content-Type・本文を順に確認し、構文が正しいJSONかどうかと、データの中身がアプリの想定に合うかを切り分けましょう。

JSON.parseのUnexpected tokenは何を示す?

JSON.parseは、引数をJSONとして読み取れない場合にSyntaxErrorを投げます。文言や位置情報の表示はJavaScriptエンジン・環境によって異なり、「Unexpected token」以外の表現になることもあります。

エラーにつながる入力例 主な原因 確認方法
{'name':'A'} シングルクォートでJSON文字列を囲む JSONではダブルクォートが必要
{name:"A"} プロパティ名の引用符がない "name"の形式にする
{"name":"A",} 末尾のカンマ 最後の要素の直後のカンマを外す
<html>…</html> HTMLレスポンスをJSON扱い APIのステータスと本文種類を調べる
空文字列 解析可能なJSON値がない レスポンス204などを区別する

用語解説:SyntaxError
JavaScriptが規定の構文として読み取れないときに出るエラー型。JSON.parseでは受信テキストがJSON文法に合わない場合に発生します。


手順1:どの文字列をparseしているか特定する

アプリのどこでJSON.parseが呼ばれたかスタックトレースを確認し、直前に渡した値の種類をチェックします。実サービスでは入力本文をそのままログへ出すと認証情報・個人情報が混ざることがあるため注意が必要です。

function parseJsonSafely(raw) {
  if (typeof raw !== "string") {
    throw new TypeError("JSON用の文字列を指定してください");
  }

  try {
    return JSON.parse(raw);
  } catch (error) {
    if (error instanceof SyntaxError) {
      throw new Error("JSON形式の入力ではありません", {
        cause: error
      });
    }
    throw error;
  }
}

この例は原因を判別する入口です。実務では、入力種別・長さ・処理の発生箇所など、機微情報を含まない情報を記録し、本文全体を無条件にログ出力しないようにします。


手順2:JSON文法を見直す

最も一般的なのは、JavaScriptオブジェクトとしては見慣れた記法をJSON文字列へ使ってしまうことです。小さな入力例で比べると違いが分かります。

// JavaScriptの文字列として正しいがJSONとしては不正
const invalid = "{'name': 'A',}";
try {
  JSON.parse(invalid);
} catch (error) {
  console.log(error instanceof SyntaxError); // true
}

const valid = '{"name": "A"}';
console.log(JSON.parse(valid).name); // A

JSONのプロパティ名と文字列値はダブルクォートで囲み、末尾のカンマを付けません。JavaScriptのオブジェクトリテラルとJSON文字列は同じ文法ではありません。

誤りの例 直し方
シングルクォートの文字列 JSON内部をダブルクォートへ
末尾のカンマ 余計なカンマを取り除く
undefinedやNaN JSONとして許される値へ変換する
JavaScriptコメント コメントを除去する
複数のJSON値を連結 1つのJSONデータとして設計する

手順3:「Unexpected token <」ならHTMLレスポンスを疑う

APIのJSONを受け取るつもりがログイン画面・404ページ・サーバーエラーのHTMLを受信していた場合、先頭にタグの記号が現れ、JSONとして解析できません。エラー文字列の「<」は一例であり、必ずこの文言になるとは限りません。

const response = await fetch("/api/users");

if (!response.ok) {
  throw new Error("HTTP " + response.status);
}

const contentType = response.headers.get("content-type") ?? "";

if (!contentType.toLowerCase().includes("json")) {
  throw new Error("JSONでない応答が返りました");
}

const data = await response.json();
console.log(Array.isArray(data));

response.json()の内部でもJSONの解析が行われます。返ってきたHTTPステータスとContent-Typeを先に見ることで、APIがJSONではない応答を返した原因を調べやすくなります。Content-Typeは自己申告なので、JSONと書かれていても本文まで正しいとは限りません。

これはJSON応答を必須とするAPI向けのガード例です。Content-Typeが省略されたAPIや独自メディアタイプでは、契約に合わせて判定条件を調整してください。

手順4:204や空本文をJSON.parseへ渡さない

APIが204 No Contentを返した場合は、正常終了でも応答本文がありません。空文字に対してJSON.parseやresponse.jsonを呼ぶとSyntaxErrorになるため、本文が必要なAPIかどうかを先に判断しましょう。

async function loadItems() {
  const response = await fetch("/api/items");

  if (!response.ok) {
    throw new Error("HTTP " + response.status);
  }

  if (response.status === 204) {
    return null;
  }

  const body = await response.text();

  if (body.trim().length === 0) {
    throw new Error("JSON本文が空でした");
  }

  return JSON.parse(body);
}

一度response.text()で読んだ本文は、同じResponseからもう一度response.json()で読むことは通常できません。どちらか一方を選んでください。この例は空本文を別のエラーへ切り分ける設計で、実際のAPI仕様に合わせてnullやエラーを選びます。

手順5:構文エラーとデータの型違いを分ける

JSON.parseでエラーが出なければ、それは「構文として正しいJSONだった」という意味です。オブジェクトのnameが文字列である、itemsが配列である、といったアプリ固有の条件まで保証しません。

const value = JSON.parse('{"items": [1, 2, 3]}');

if (
  typeof value !== "object" ||
  value === null ||
  !Array.isArray(value.items)
) {
  throw new Error("itemsが配列ではありません");
}

console.log(value.items.length);

利用するデータが外部API由来の場合は、必要に応じてスキーマバリデーションライブラリや明示的な型検査を導入し、構文チェックとデータ検証を分離します。

実務で多い原因と診断順

  • コンソールのエラー位置と例外の種類を確認する。
  • JSON.parseへ渡す値が文字列か、空でないか調べる。
  • JSON構文(ダブルクォート・カンマ・コメント・undefined)を点検する。
  • APIの場合はHTTP statusとContent-Typeを確認する。
  • JSONとして解析できた後は、期待するプロパティと型を確認する。

APIが意図せずログイン画面を返した場合は、通信先URL、認証切れ、リダイレクト、プロキシ設定を調べます。CORSの制約でレスポンス自体を受け取れない場合はJSON構文以前の問題として扱ってください。

関連するJSON・非同期通信の記事

JSONの構文やデータ設計を復習したい場合は既存のJSON解説記事へ進むと理解しやすくなります。APIとfetchの基本的な動きを確認するならAjax入門も役立ちます。

(JSON文法とデータ設計については『JSON完全ガイド|基礎からAPI連携・設計原則・エラー解決まで』をご参照ください)

(APIレスポンスを受け取る手順については『JavaScriptのAjax完全入門|fetchの使い方・CORSエラーの対処・非同期通信の基本を解説』をご参照ください)

よくある質問とまとめ

JSON.parseのエラーはJavaScriptエンジンによって違いますか?

はい。エラー文言や位置表示は環境によって異なります。まずSyntaxErrorであることと渡した入力を確認しましょう。

JSON.parseで構文が正しければ型検査は不要ですか?

不要にはなりません。JSONとして有効でも、期待する構造や型と一致するかは別に確認します。

fetchは成功なのにJSON.parseで落ちるのはなぜ?

HTTP通信に成功しても、本文がHTML、空、または構文不正なJSONなら解析エラーになります。status、Content-Type、本文の形式を順に確認します。

JSON.parseのUnexpected tokenは、受信データをJSON文法として解釈できないことを知らせるエラーの一種です。入力の種類、文法、HTTPレスポンス、空本文、スキーマを分けて確認すると原因に近づけます。

まずはエラーが出た場所のJSON.parseの引数を確認し、APIの場合はステータスとContent-Typeから調べてみてください。

カジュアル面談はこちら

すべてを開示している会社です

ポジティブな面もネガティブな面も、包み隠さず誠実にお答えします。
気になることがあれば、面談の際にすべてオープンにお話します。