Nenhuma causa visível para "Token inesperado ilegal"

270

Estou recebendo este erro JavaScript no meu console:

Untaught SyntaxError: token inesperado ILLEGAL

Este é o meu código:

var foo = 'bar';​

É super simples, como você pode ver. Como isso pode estar causando um erro de sintaxe?

bfavaretto
fonte
9
Para futuros leitores: se você encontrou este erro ao usar o Vagrant - esta resposta também pode ser útil: stackoverflow.com/questions/9479117/…
OZ_
Caso você esteja enfrentando isso no WordPress, enfileire os scripts em functions.php. Eu tinha um modelo específico em que estava chamando o JS diretamente do modelo. Mudar para um enfileiramento condicional em wp_head ou wp_footer resolveu isso.
Alpesh Shah
7
Nota do moderador: excluí aqui várias respostas que não respondem à pergunta. Repito , este não é um lugar para listar todas as coisas possíveis que você pode fazer em JavaScript que resultarão nesse erro. A pergunta tem uma circunstância muito específica que não envolve nenhum desses cenários e todos esses exemplos simplesmente não respondem à pergunta.
animuson
3
Uau, a polícia de SO teve um dia de campo com essa pergunta. Felizmente, algumas das informações relevantes ainda estão visíveis nas respostas excluídas.
Cdonner

Respostas:

493

O erro

Quando o código é analisado pelo interpretador JavaScript, ele é dividido em pedaços chamados "tokens". Quando um token não pode ser classificado em um dos quatro tipos básicos de token , ele é rotulado como "ILEGAL" na maioria das implementações e esse erro é gerado.

O mesmo erro é gerado se, por exemplo, você tentar executar um arquivo js com um @caractere não autorizado, chaves entre aspas, colchetes, colchetes, "aspas inteligentes", aspas simples não incluídas corretamente (por exemplo this.run('dev1)) e assim por diante.

Muitas situações diferentes podem causar esse erro. Mas se você não tiver nenhum erro óbvio de sintaxe ou caractere ilegal, poderá ser causado por um caractere ilegal invisível . É disso que trata esta resposta.

Mas não vejo nada ilegal!

Há um caractere invisível no código, logo após o ponto e vírgula. É o caractere U+200Bde espaço de largura zero Unicode (também conhecido como ZWSPentidade HTML ​). Esse caractere é conhecido por causar o Unexpected token ILLEGALerro de sintaxe do JavaScript.

E de onde veio?

Não sei ao certo, mas minha aposta está no jsfiddle . Se você colar código a partir daí, é muito provável que inclua um ou mais U+200Bcaracteres. Parece que a ferramenta usa esse caractere para controlar a quebra de linha em seqüências longas.

UPDATE 2013-01-07

Após a atualização mais recente do jsfiddle , agora ele mostra o caractere como um ponto vermelho, como o codepen. Aparentemente , também não está mais inserindo U+200Bcaracteres por conta própria, portanto esse problema deve ser menos frequente a partir de agora.

ATUALIZAÇÃO 17-03-2015

Às vezes, o Vagrant também causa esse problema, devido a um erro no VirtualBox . A solução, de acordo com esta postagem do blog, é definir sendfile off;sua configuração do nginx ou EnableSendfile Offse você usa o Apache.

Também foi relatado que o código colado nas ferramentas de desenvolvedor do Chrome pode incluir esse caractere, mas não foi possível reproduzi-lo com a versão atual (22.0.1229.79 no OSX).

Como posso identificá-lo?

O personagem é invisível, como sabemos que está lá? Você pode pedir ao seu editor para mostrar caracteres invisíveis. A maioria dos editores de texto possui esse recurso. O Vim, por exemplo, os exibe por padrão e os ZWSPshows como <u200b>. Você também pode depurá- lo on-line: jsbin exibe o caractere como um ponto vermelho em seus painéis de código (mas parece removê-lo após salvar e recarregar a página). O CodePen.io também o exibe como um ponto e o mantém mesmo após o salvamento.

Problemas relacionados

Esse personagem não é algo ruim, pode realmente ser bastante útil. Este exemplo na Wikipedia demonstra como ele pode ser usado para controlar onde uma cadeia longa deve ser quebrada para a próxima linha. No entanto, se você não tem conhecimento da presença do personagem na sua marcação, isso pode se tornar um problema. Se você o tiver dentro de uma string (por exemplo, o nodeValueelemento DOM que não possui conteúdo visível), você poderá esperar que essa string esteja vazia, quando na verdade não está (mesmo após a aplicação String.trim).

ZWSPtambém pode fazer com que espaços em branco extras sejam exibidos em uma página HTML, por exemplo, quando é encontrada entre dois <div>elementos (como visto nesta pergunta ). Esse caso nem é reproduzível no jsfiddle, pois o personagem é ignorado lá.

Outro problema em potencial: se a codificação da página da web não for reconhecida como UTF-8, o caractere poderá realmente ser exibido (como ​em latin1, por exemplo).

Se ZWSPestiver presente no código CSS (código embutido ou uma folha de estilo externa), os estilos também não poderão ser analisados ​​corretamente; portanto, alguns estilos não serão aplicados (como visto nesta pergunta ).

A especificação ECMAScript

Não pude encontrar nenhuma menção a esse caractere específico na especificação ECMAScript (versões 3 e 5.1 ). A versão atual menciona caracteres semelhantes ( U+200Ce U+200D) na Seção 7.1 , que afirma que eles devem ser tratados como IdentifierParts quando "fora dos comentários, literais de seqüência de caracteres e literais de expressão regular". Esses caracteres podem, por exemplo, fazer parte de um nome de variável (e de var x\u200c;fato funciona).

A Seção 7.2 lista os caracteres de espaço em branco válidos (como tabulação, espaço, espaço sem interrupção etc.) e menciona vagamente que qualquer outro "separador de espaço" Unicode (categoria "Zs") deve ser tratado como espaço em branco. Provavelmente não sou a melhor pessoa para discutir as especificações a esse respeito, mas parece-me que U+200Bdeve ser considerado um espaço em branco de acordo com isso, quando, na verdade, as implementações (pelo menos Chrome e Firefox) parecem tratá-las como um inesperado token (ou parte de um), causando o erro de sintaxe.

bfavaretto
fonte
codepen.io também parece exibir esse caractere. VIM e VI, também o bloco de notas ++ o exibe.
Rlemon
Obrigado @rlemon, adicionou um exemplo do CodePen à resposta. Site legal, eu não sabia.
precisa saber é o seguinte
Deparei com esse mesmo problema ao copiar / colar o código da classe testTwo desta pergunta SO usando o Chromium. Aparentemente, o analisador engasgou com o realce da sintaxe da functionpalavra - chave, que era invisível no Vim até que eu o destacasse usando o método de perguntas frequentes "Destacar todos os caracteres não imprimíveis". Ahh, seria tão bom se houvesse uma maneira de copiar apenas caracteres no intervalo de 32..127 (mas provavelmente existe um aplicativo para isso :))
ack
1
@bfavaretto, apenas no snippet de código no modo de edição. Não está no corpo da questão, deveria ter mencionado isso. (Testado no Chrome 43.0.2357.124 m)
Fernando Leal
1
Muitos editores de texto permitem alternar a codificação de caracteres de um arquivo. Isso é tremendamente útil para encontrar personagens ofensivos como esses. Minha solução foi alternar temporariamente de UTF-8 para uma codificação ANSI, remover os caracteres inválidos e voltar. Eu usei o freeware Notepad ++ no Windows. Edição: Acontece que eu perdi a opção Notepad ++ para "Exibindo todos os caracteres". Mesmo resultado, menos problemas: D
mbargiel 22/03
64

por que você está procurando esse problema no seu código? Mesmo se for copypasted.

Se você pode ver, o que exatamente está acontecendo após salvar o arquivo na pasta sincronizada - você verá algo como *****no final do arquivo. Não está relacionado ao seu código.

Solução.

Se você estiver usando nginxna caixa vagrant - adicione à configuração do servidor:

sendfile off;

Se você estiver usando apachena caixa vagrant - adicione à configuração do servidor:

EnableSendfile Off;

Origem do problema: Bug do VirtualBox

Nikolay Fominyh
fonte
6
Você literalmente salvou meu dia. Eu lutei com o Nginx + Vagrant por uma noite inteira, e isso resolveu o problema.
Fradeve
2
Será que não esperam que este seja a resposta certa (para mim) mas foi, muito obrigado.
Charlotte
2
Na verdade, ele parou de funcionar. Então, novamente, há várias camadas de ligação simbólica em jogo aqui, então eu apenas desfiz o que pude.
Charlotte
Obrigado - eu estava em uma caixa de vagabundos com nginx. Eu também vi esse problema em configurações semelhantes do Apache.
Cameron
para apache: EnableSendfile Off
jamlee 21/03
7

Isso também pode estar acontecendo se você estiver copiando o código de outro documento (como um PDF) para o console e tentando executá-lo.

Eu estava tentando executar um código de exemplo de um livro Javascript que estava lendo e fiquei surpreso por não ter sido executado no console.

Aparentemente, a cópia do PDF introduz alguns caracteres inesperados, ilegais e invisíveis no código.

Kyle Pennell
fonte
5

Eu tive o mesmo problema no meu mac e achei que era porque o Mac estava substituindo as aspas padrão por aspas encaracoladas, que são caracteres javascript ilegais.

Para corrigir isso, tive que alterar as configurações no meu mac Preferências do sistema => Teclado => Texto (guia) desmarque usar aspas e traços inteligentes (o padrão foi verificado).

user3360944
fonte
5

Eu recebi esse erro no chrome quando tinha uma sequência não terminada após a linha que o erro apontava. Depois de fechar a string, o erro desapareceu.

Exemplo com erro:

var file = files[i]; // SyntaxError: Unexpected token ILLEGAL

jQuery('#someDiv').innerHTML = file.name + " (" + formatSize(file.size) + ") "
    + "<a href=\"javascript: something('"+file.id+');\">Error is here</a>";

Exemplo sem erro:

var file = files[i]; // No error

jQuery('#someDiv').innerHTML = file.name + " (" + formatSize(file.size) + ") "
    + "<a href=\"javascript: something('"+file.id+"');\">Error was here</a>";
Ozzy
fonte
2
Eu tive que fazer uma diferença nos seus dois exemplos para descobrir a diferença e, uma vez que fiz isso, descobri imediatamente meu próprio problema.
Ben Harold
3

Se você estiver executando uma instalação do nginx + uwsgi vagrant, o principal problema é o bug da caixa Virtual com o arquivo de envio, conforme mencionado em algumas das respostas. No entanto, para resolvê-lo, é necessário desativar o sendfile no nginx e no uwsgi.

  1. No arquivo nginx.conf sendfile off

  2. uwsgi application / config --disable-sendfile

msrivas
fonte
2

Ao executar o OS X, o sistema de arquivos cria garfos ocultos basicamente de todos os seus arquivos, se estiverem em um disco rígido que não suporta HFS +. Às vezes, isso (aconteceu comigo agora) leva o seu mecanismo JavaScript a tentar executar a bifurcação de dados em vez do código que você pretende executar. Quando isso acontecer, você também receberá

SyntaxError: Unexpected token ILLEGAL

porque a bifurcação de dados do seu arquivo conterá o caractere Unicode U + 200B. A remoção do arquivo de bifurcação de dados fará com que seu script execute o código pretendido real, em vez de um bifurcação de dados binários do seu código.

. o que quer que seja: Esses arquivos são criados em volumes que não oferecem suporte nativo às características completas dos arquivos HFS (por exemplo, volumes ufs, compartilhamento de arquivos do Windows, etc.). Quando um arquivo Mac é copiado para esse volume, seu fork de dados é armazenado com o nome regular do arquivo e as informações adicionais do HFS (fork de recursos, tipo e códigos de criador, etc.) são armazenadas em um segundo arquivo (no formato AppleDouble), com um nome que começa com ". ". (Esses arquivos são, é claro, invisíveis no que diz respeito ao OS-X, mas não a outros sistemas operacionais; isso às vezes pode ser irritante ...)

Spcaeyob
fonte
1

Aqui está o meu motivo:

antes:

var path = "D:\xxx\util.s"

que \ué uma fuga, descobri usando o JS de análise do Codepen .

depois de:

var path = "D:\\xxx\\util.s"

e o erro foi corrigido

Miao1007
fonte
0

Eu tive esse mesmo problema e ocorreu porque havia pressionado a tecla Enter ao adicionar código em uma sequência de texto.

Como era uma longa sequência de texto, eu queria ver tudo sem precisar rolar no meu editor de texto, no entanto, pressionar Enter adicionou um caractere invisível à sequência, o que era ilegal. Eu estava usando Sublime Text como meu editor.

Jordan Davis
fonte
0

Mudei todas as áreas espaciais para o & nbsp, exatamente assim e funcionou sem problemas.

val.replace ("", "& nbsp");

Eu espero que isso ajude alguém.

Erdogan
fonte
0

Vou adicionar mais uma resposta à pilha. Este problema pode acontecer também devido à codificação. Você deseja que a codificação utf8 esteja do lado seguro. Alguns editores, por padrão, usam utf16, o que pode causar problemas. Uma maneira rápida de testar isso é, por exemplo, no código VS, simplesmente recrie o mesmo conteúdo, mas use o editor local do vscode para criar o arquivo. Espero que isso ajude alguns.

rezeli
fonte