leer - manejo de archivos en javascript
¿Cómo manejo las nuevas líneas en JSON? (7)
Encontré ese problema al crear una clase en PHP4 para emular json_encode (disponible en PHP5). Esto es lo que se me ocurrió:
class jsonResponse {
var $response;
function jsonResponse() {
$this->response = array(''isOK''=>''KO'',''msg''=>''Undefined'');
}
function set($isOK, $msg) {
$this->response[''isOK''] = ($isOK) ? ''OK'' : ''KO'';
$this->response[''msg''] = htmlentities($msg);
}
function setData($data=null) {
if(!is_null($data))
$this->response[''data''] = $data;
elseif(isset($this->response[''data'']))
unset($this->response[''data'']);
}
function send() {
header(''Content-type: application/json'');
echo ''{"isOK":"''.$this->response[''isOK''].''","msg":''.$this->parseString($this->response[''msg'']);
if(isset($this->response[''data'']))
echo '',"data":''.$this->parseData($this->response[''data'']);
echo ''}'';
}
function parseData($data) {
if(is_array($data)) {
$parsed = array();
foreach ($data as $key=>$value)
array_push($parsed, $this->parseString($key).'':''.$this->parseData($value));
return ''{''.implode('','', $parsed).''}'';
} else
return $this->parseString($data);
}
function parseString($string) {
$string = str_replace("//", "////", $string);
$string = str_replace(''/'', "///", $string);
$string = str_replace(''"'', "//".''"'', $string);
$string = str_replace("/b", "//b", $string);
$string = str_replace("/t", "//t", $string);
$string = str_replace("/n", "//n", $string);
$string = str_replace("/f", "//f", $string);
$string = str_replace("/r", "//r", $string);
$string = str_replace("/u", "//u", $string);
return ''"''.$string.''"'';
}
}
Seguí las reglas mencionadas here . Solo utilicé lo que necesitaba, pero creo que puede adaptarlo a sus necesidades en el idioma que esté usando. El problema en mi caso no era sobre las nuevas líneas como pensé originalmente, sino sobre el hecho de que no se escapó. Espero que esto evite a alguien más el pequeño dolor de cabeza que tuve al descubrir qué hice mal.
He generado algo de JSON y estoy intentando insertarlo en un objeto en JavaScript. Sigo recibiendo errores. Esto es lo que tengo:
var data = ''{"count" : 1, "stack" : "sometext/n/n"}'';
var dataObj = eval(''(''+data+'')'');
Esto me da un error:
unterminated string literal
Con JSON.parse(data)
, veo mensajes de error similares: " JSON.parse(data)
Unexpected token ↵
" en Chrome y " unterminated string literal
" en Firefox e IE.
Cuando saco el /n
después de sometext
el error desaparece en ambos casos. Parece que no puedo entender por qué /n
hace que eval
y JSON.parse
fallen.
Es posible que desee ver esta función de C # para escapar de la cadena:
http://www.aspcode.net/C-encode-a-string-for-JSON-JavaScript.aspx
public static string Enquote(string s)
{
if (s == null || s.Length == 0)
{
return "/"/"";
}
char c;
int i;
int len = s.Length;
StringBuilder sb = new StringBuilder(len + 4);
string t;
sb.Append(''"'');
for (i = 0; i < len; i += 1)
{
c = s[i];
if ((c == ''//') || (c == ''"'') || (c == ''>''))
{
sb.Append(''//');
sb.Append(c);
}
else if (c == ''/b'')
sb.Append("//b");
else if (c == ''/t'')
sb.Append("//t");
else if (c == ''/n'')
sb.Append("//n");
else if (c == ''/f'')
sb.Append("//f");
else if (c == ''/r'')
sb.Append("//r");
else
{
if (c < '' '')
{
//t = "000" + Integer.toHexString(c);
string t = new string(c,1);
t = "000" + int.Parse(tmp,System.Globalization.NumberStyles.HexNumber);
sb.Append("//u" + t.Substring(t.Length - 4));
}
else
{
sb.Append(c);
}
}
}
sb.Append(''"'');
return sb.ToString();
}
Hola, utilicé esta función para eliminar la nueva línea u otros caracteres en los datos para analizar los datos JSON:
function normalize_str($str) {
$invalid = array(''Š''=>''S'', ''š''=>''s'', ''Đ''=>''Dj'', ''đ''=>''dj'', ''Ž''=>''Z'', ''ž''=>''z'',
''Č''=>''C'', ''č''=>''c'', ''Ć''=>''C'', ''ć''=>''c'', ''À''=>''A'', ''Á''=>''A'', ''Â''=>''A'', ''Ã''=>''A'',
''Ä''=>''A'', ''Å''=>''A'', ''Æ''=>''A'', ''Ç''=>''C'', ''È''=>''E'', ''É''=>''E'', ''Ê''=>''E'', ''Ë''=>''E'',
''Ì''=>''I'', ''Í''=>''I'', ''Î''=>''I'', ''Ï''=>''I'', ''Ñ''=>''N'', ''Ò''=>''O'', ''Ó''=>''O'', ''Ô''=>''O'',
''Õ''=>''O'', ''Ö''=>''O'', ''Ø''=>''O'', ''Ù''=>''U'', ''Ú''=>''U'', ''Û''=>''U'', ''Ü''=>''U'', ''Ý''=>''Y'',
''Þ''=>''B'', ''ß''=>''Ss'', ''à''=>''a'', ''á''=>''a'', ''â''=>''a'', ''ã''=>''a'', ''ä''=>''a'', ''å''=>''a'',
''æ''=>''a'', ''ç''=>''c'', ''è''=>''e'', ''é''=>''e'', ''ê''=>''e'', ''ë''=>''e'', ''ì''=>''i'', ''í''=>''i'',
''î''=>''i'', ''ï''=>''i'', ''ð''=>''o'', ''ñ''=>''n'', ''ò''=>''o'', ''ó''=>''o'', ''ô''=>''o'', ''õ''=>''o'',
''ö''=>''o'', ''ø''=>''o'', ''ù''=>''u'', ''ú''=>''u'', ''û''=>''u'', ''ý''=>''y'', ''ý''=>''y'', ''þ''=>''b'',
''ÿ''=>''y'', ''Ŕ''=>''R'', ''ŕ''=>''r'', "`" => "''", "´" => "''", ''"'' => '','', ''`'' => "''",
''´'' => "''", ''"'' => ''/"'', ''"'' => "/"", ''´'' => "''", "’" => "''", "{" => "",
"~" => "", "–" => "-", "''" => "''"," " => " ");
$str = str_replace(array_keys($invalid), array_values($invalid), $str);
$remove = array("/n", "/r/n", "/r");
$str = str_replace($remove, "//n", trim($str));
//$str = htmlentities($str,ENT_QUOTES);
return htmlspecialchars($str);
}
echo normalize_str($lst[''address'']);
Necesitará tener una función que reemplace /n
a //n
en caso de que los data
no sean una cadena literal.
function jsonEscape(str) {
return str.replace(//n/g, "////n").replace(//r/g, "////r").replace(//t/g, "////t");
}
var data = ''{"count" : 1, "stack" : "sometext/n/n"}'';
var dataObj = JSON.parse(jsonEscape(data));
El dataObj
resultante será
Object {count: 1, stack: "sometext/n/n"}
Podría simplemente escapar de su cadena en el servidor cuando escriba el valor del campo json y desbloquearlo cuando recupere el valor en el navegador del cliente, por ejemplo.
La implementación javascript de todos los principales navegadores tiene el comando unescape.
Ejemplo: en el servidor:
response.write "{""field1"":""" & escape(RS_Temp("textField")) & """}"
en el navegador:
document.getElementById("text1").value = unescape(jsonObject.field1)
Según las especificaciones: http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf
A string is a sequence of Unicode code points wrapped with quotation marks
(U+0022). All characters may be placed within the quotation marks except for the
characters that must be escaped: quotation mark (U+0022), reverse solidus
(U+005C), and the control characters U+0000 to U+001F. There are two-character
escape sequence representations of some characters.
Así que no puedes pasar los códigos 0x0A
o 0x0C
directamente. ¡Está prohibido! Spec sugiere usar secuencias de escape para algunos códigos bien definidos desde U+0000
hasta U+001F
:
/f represents the form feed character (U+000C).
/n represents the line feed character (U+000A).
Como la mayoría de los lenguajes de programación usa /
para citar, debe escapar la sintaxis de escape (doble escape: una vez para lenguaje / plataforma, una vez para Json):
jsonStr = "{ /"name/": /"Multi//nline./" }";
Supongo que esto es lo que quieres:
var data = ''{"count" : 1, "stack" : "sometext//n//n"}'';
(Debe escapar de la "/" en su cadena (convertirla en un doble - "/"), de lo contrario se convertirá en una nueva línea en la fuente JSON, no en los datos de JSON.)