JSONPで受け取れない文字? \u2028

  • 39
    Like
  • 2
    Comment
More than 1 year has passed since last update.

半日以上かかってしまった!

JSONPで返却する文字列に\u2028が含まれているとブラウザで
扱えない模様。

任意のURLを指定するとその内容をJSONPで返していたのだが、
特定のページがなぜかエラーとなってしまい、原因に時間がかかった。

JSON.stringifyすりゃ、デコード絶対出来るものと思い込んでいた

ちなみに、JSON.stringifyしてJSONPで返す文字列を作成していたので、
余計に時間がかかった気がする。

どんなエラーが出るのか?

Chromeでは

Uncaught SyntaxError: Unexpected token ILLEGAL 

Firefoxでは

SyntaxError: unterminated string literal 

\u2028のほか\u2029も問題になる模様

2014/10/25追記

コメントでご指摘いただき、改めて分かりづらかったので、
コードでどんな事だったかを残しておきます。

function callback(obj) {
    console.dir(obj);
}

function myEscape(str) {
    //return str;
    return str.replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
}

var cb = "callback(" + myEscape(JSON.stringify(["\u2028", "\u2029"])) + ")";
console.log(cb);

var s = document.createElement("script");
s.innerHTML = cb;
document.body.appendChild(s);

// myEscapeで\u2028,\u2029をエスケープしないと後処理でエラーになる。
// 実際のケースでは、JSONPで受けた側でコールバック実行直前でエラーとなる。
cb = "callback(" + myEscape(JSON.stringify(["b\u2028a", "d\u2029c"])) + ")";
console.log(cb);

s = document.createElement("script");
//本来はここでsrc属性にJSONP対応のWebAPIを指定する。
s.innerHTML = cb;
document.body.appendChild(s);

Runstantでこれを動かせるようにしておきました。

関連するリンク

原因が「\u2028」と分かってからは、類似の情報は容易に見つかった。

関連記事