2010-12-19 2 views
1

J'ai un message de serveur envoyé via des sockets Web. ce message est une chaîne json (validée). quand il arrive au navigateur je vérifie que c'est une chaîne avec typeof(data) et il me dit que c'est, en fait, une chaîne. Quand finalement je fais var some_obj = eval('(' + data + ')'); il me donne une erreur Uncaught SyntaxError: Unexpected token ILLEGAL.Y a-t-il une différence entre les chaînes entre guillemets simples/doubles passées à eval de javascript?

également, avant d'utiliser eval(), i console.log(data) et il affiche correctement, bien qu'un alert(data) n'affichera rien sur la boîte de dialogue.

Je n'arrive pas à comprendre ce qui se passe.

J'ai également essayé var myJson = '{ "x": "Hello, World!", "y": [1, 2, 3] }'; puis var myObj = eval('(' + myJson + ')'); et cela fonctionne, donc je ne peux vraiment pas comprendre pourquoi le mien ne peut pas être évalué (analysé).

la chaîne reçue via les sockets web est la suivante:

received 37 bytes » { "cmd": "setname", "params": "ok" } 

data = { "cmd": "setname", "params": "ok" } (avec des guillemets, je suppose, en raison de typeof(data) être = string).

des conseils? merci

edit1 »avec web-sockets, vous devez ajouter un caractère nul (0 ascii) et ajouter un caractère d'échappement (255 ascii) à la chaîne de sortie du serveur. Je suppose que le client (navigateur) comme il implémente web-sockets doit faire face à cela et déplier la chaîne correctement (comme le standard) et comme je le fais dans mon serveur. chose est, il pourrait y avoir un échappement char gauche et il ne traite pas correctement. mais le problème a seulement commencé quand j'ai essayé d'envoyer des chaînes JSON pour être eval() ed. sinon, ils fonctionnent correctement comme toute autre chaîne.

+0

Vous devez comprendre que les guillemets au début (et à la fin) sont seulement là pour vous et l'analyseur pour comprendre où une chaîne commence (et se termine). Ils ne font pas partie de la chaîne elle-même. – ZeissS

+0

Êtes-vous ** sure ** 'typeof (data)' est 'String'? Vous ne mentionnez pas 'console.log' ceci. Je pense que vous obtiendriez le beaviour que vous décrivez si les données étaient un objet littéral et non en fait une chaîne. – Day

+0

typeof (d) »chaîne. Uncaught SyntaxError: jeton inattendu ILLEGAL. il y a en fait quelque chose de drôle qui se passe »quand j'essaie de copier depuis la console, le 'd' (chaîne) avec du texte avant, il ne copie pas ...» console.log ('received' + d.length + 'bytes »'+ D); c'est la commande log et elle génère »37 octets reçus» {"cmd": "setname", "params": "ok"} mais je dois l'écrire manuellement car je ne suis pas capable de le copier! – mwm

Répondre

6

Non, il n'y a pas de différence entre " et ' pour citer les chaînes autres que vous pouvez utiliser " sans échapper à l'intérieur d'une chaîne entre guillemets avec ' et vice-versa. Mais je ne pense pas que (le titre de votre question) ait quelque chose à voir avec le problème que vous avez.

Re votre édition, si vous voulez vous assurer qu'il n'y a pas de caractères avec la valeur 0 ou 255 dans la chaîne, vous pouvez le faire comme ceci:

data = data.replace(/[\u0000\u00ff]/g, ''); 

... avant de passer à eval . Et il semblerait que vous vouliez faire cela, puisque votre chose dit qu'il a reçu 37 octets mais que la chaîne n'a que 36 caractères et n'utilise aucun caractère nécessitant deux octets (ou peut-être qu'il y a juste un espace à la fin ne peut pas voir).

Hors-sujet: Il est préférable de ne pas utiliser eval pour désérialiser JSON. Au lieu de cela, utilisez une bibliothèque qui le gère directement. Crockford a deux bibliothèques non eval différentes sur his github page, une (json_parse.js) qui utilise un analyseur récursif-descendant et une autre (json_parse_state.js) qui utilise une machine d'état. Si vous voulez vraiment, vraiment utiliser eval pour analyser JSON, jetez un oeil à son implémentation dans json2.js, qui prend au moins quelques mesures pour éliminer les éléments malveillants.

Hors-sujet 2: Re

where data = { "cmd": "setname", "params": "ok" } (with quotes i suppose, because of typeof(data) being = string).

Nous utilisons uniquement des citations à littéraux chaîne de citation dans le code; il n'y a pas de guillemets autour des données de chaîne réelles en mémoire. Si je fais ceci:

var foo = "bar"; 

... la chaîne qui foo des points à composé uniquement des caractères b, a et r. Il n'y a pas de devis les guillemets sont seulement là dans le code pour dire à l'analyseur que ce qui suit est un littéral de chaîne.

+0

en fait, je n'utilise pas eval(). J'utilise json2.js avec JSON.parse() mais les deux me donnent le même résultat ... je vais essayer votre data.replace() merci.EDIT »j'ai fait d = d.replace (/ [\ u0000 - \ u00ff]/g, ''); mais maintenant d est vide (0 longueur) mais toujours typeof (d) = chaîne – mwm

+1

@mwm: Je crains que vous ayez vu une version provisoire où j'avais tapé '-' où je n'aurais pas dû. La regex correcte est (maintenant) montrée ci-dessus (il suffit de supprimer le '-'). :-) V. embarrassant, j'espérais que je l'avais attrapé avant que quiconque ne le voit, mais apparemment pas. –

+0

Eh bien, je devrais apprendre quelques regex aussi. Je vous remercie. ça a vraiment marché! ce qui signifie que j'avais raison, en supposant que certains caractères d'implémentation de sockets Web étaient en conflit. Je pensais que le navigateur déroulait la chaîne correctement. merci beaucoup @ T.J. Crowder – mwm

Questions connexes