ไม่มีสาเหตุที่มองเห็นได้สำหรับ“ โทเค็นที่ไม่คาดคิด ILLEGAL”


270

ฉันได้รับข้อผิดพลาด JavaScript บนคอนโซลของฉัน:

Uncaught SyntaxError: โทเค็นที่ไม่คาดคิด ILLEGAL

นี่คือรหัสของฉัน:

var foo = 'bar';​

มันง่ายมากอย่างที่คุณเห็น มันจะทำให้เกิดข้อผิดพลาดทางไวยากรณ์ได้อย่างไร


9
สำหรับผู้อ่านในอนาคต: หากคุณพบข้อผิดพลาดนี้เมื่อใช้ Vagrant - คำตอบนี้อาจมีประโยชน์เช่น: stackoverflow.com/questions/9479117/…
OZ_

ในกรณีที่คุณประสบปัญหานี้ใน WordPress ให้เข้าสู่สคริปต์จาก functions.php ฉันมีแม่แบบเฉพาะที่ฉันเรียกใช้ JS โดยตรงจากแม่แบบ การสลับไปยังการจัดคิวตามเงื่อนไขใน wp_head หรือ wp_footer แก้ไขปัญหานี้
Alpesh Shah

7
หมายเหตุของผู้ดำเนินรายการ:ฉันลบคำตอบจำนวนมากที่นี่ซึ่งไม่ได้ตอบคำถามจริง นี่ไม่ใช่ฉันไม่พูดซ้ำสถานที่ที่จะแสดงรายการทุกสิ่งที่เป็นไปได้ที่คุณสามารถทำได้ใน JavaScript ที่จะทำให้เกิดข้อผิดพลาดนี้ คำถามมีสถานการณ์ที่เฉพาะเจาะจงมากที่ไม่เกี่ยวข้องกับสถานการณ์เหล่านั้นและตัวอย่างเหล่านั้นทั้งหมดไม่ตอบคำถาม
animuson

3
ว้าวตำรวจ SO มีวันฟิลด์ด้วยคำถามนี้ โชคดีที่ข้อมูลที่เกี่ยวข้องบางส่วนยังคงปรากฏอยู่ในคำตอบที่ถูกลบไปแล้ว
cdonner

คำตอบ:


493

ข้อผิดพลาด

เมื่อโค้ดถูกวิเคราะห์โดยล่าม JavaScript มันจะถูกแยกเป็นชิ้น ๆ ที่เรียกว่า "โทเค็น" เมื่อโทเค็นไม่สามารถจัดประเภทเป็นหนึ่งในสี่ประเภทโทเค็นพื้นฐานได้รับการติดป้าย "ILLEGAL" ในการใช้งานส่วนใหญ่และข้อผิดพลาดนี้จะถูกโยน

ยกตัวอย่างเช่นข้อผิดพลาดเดียวกันคุณพยายามเรียกใช้ไฟล์ js ด้วย@ตัวอักษรอันธพาล, วงเล็บปีกกาที่วางผิดตำแหน่ง, วงเล็บ, "คำพูดอัจฉริยะ", คำพูดเดี่ยวไม่ถูกต้อง (เช่นthis.run('dev1)) และอื่น ๆ

สถานการณ์ต่าง ๆ มากมายอาจทำให้เกิดข้อผิดพลาดนี้ แต่ถ้าคุณไม่มีข้อผิดพลาดทางไวยากรณ์ที่ชัดเจนหรือตัวอักษรผิดกฎหมายอาจเกิดจากตัวอักษรผิดกฎหมายที่มองไม่เห็น นั่นคือสิ่งที่คำตอบนี้เป็นเรื่องเกี่ยวกับ

แต่ฉันไม่เห็นสิ่งผิดกฎหมาย!

มีตัวอักษรที่มองไม่เห็นในโค้ดทันทีหลังจากอัฒภาค มันเป็นอักขระU+200Bช่องว่างความกว้างศูนย์Unicode (หรือZWSPเอนทิตี HTML ​) เป็นที่ทราบกันว่าอักขระตัวนั้นทำให้เกิดUnexpected token ILLEGALข้อผิดพลาดทางไวยากรณ์ของ JavaScript

แล้วมันมาจากไหน?

ผมไม่สามารถบอกได้แน่นอน แต่เดิมพันของฉันอยู่บนjsfiddle หากคุณวางรหัสจากที่นั่นเป็นไปได้มากว่าจะมีU+200Bอักขระอย่างน้อยหนึ่งตัว ดูเหมือนว่าเครื่องมือจะใช้อักขระนั้นเพื่อควบคุมการตัดคำบนสตริงที่ยาว

อัพเดท 2013-01-07

หลังจากที่ล่าสุดปรับปรุง jsfiddle , ตอนนี้มันแสดงให้เห็นตัวอักษรที่เป็นจุดสีแดงเหมือน codepen ไม่ เห็นได้ชัดว่ามันยังไม่ได้แทรกU+200Bตัวละครของตัวเองอีกต่อไปดังนั้นปัญหานี้ควรจะเกิดขึ้นน้อยลงนับจากนี้เป็นต้นไป

อัพเดท 2015-03-17

คนจรจัดปรากฏบางครั้งทำให้เกิดปัญหานี้เช่นกันเนื่องจากข้อผิดพลาดในVirtualBox วิธีการแก้ปัญหาตามโพสต์บล็อกนี้คือการตั้งค่าsendfile off;ในการกำหนดค่าnginx ของคุณหรือEnableSendfile Offถ้าคุณใช้ Apache

มันก็ถูกรายงานว่ารหัสที่วางจากเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ของ Chrome อาจรวมถึงตัวละครนั้น แต่ฉันไม่สามารถทำซ้ำได้ด้วยรุ่นปัจจุบัน (22.0.1229.79 บน OSX)

ฉันจะสังเกตเห็นได้อย่างไร

ตัวละครนั้นมองไม่เห็นเราจะรู้ได้อย่างไรว่ามันอยู่ที่นั่น? คุณสามารถขอให้ผู้แก้ไขของคุณแสดงตัวอักษรที่มองไม่เห็น โปรแกรมแก้ไขข้อความส่วนใหญ่มีคุณสมบัตินี้ ที่เป็นกลุ่มตัวอย่างเช่นแสดงไว้โดยค่าเริ่มต้นและแสดงให้เห็นว่าเป็นZWSP <u200b>คุณสามารถดีบักแบบออนไลน์ได้: jsbinแสดงอักขระเป็นจุดสีแดงบนบานหน้าต่างโค้ด (แต่ดูเหมือนว่าจะลบออกหลังจากบันทึกและโหลดหน้าซ้ำ) CodePen.io ยังแสดงเป็นจุดและเก็บไว้แม้หลังจากการบันทึก

ปัญหาที่เกี่ยวข้อง

ตัวละครนั้นไม่ใช่สิ่งเลวร้ายจริง ๆ แล้วมันมีประโยชน์มากทีเดียว ตัวอย่างในวิกิพีเดียนี้แสดงให้เห็นว่าสามารถใช้ในการควบคุมได้อย่างไรว่าควรห่อสตริงที่มีความยาวให้กับบรรทัดถัดไปอย่างไร อย่างไรก็ตามหากคุณไม่ทราบว่าตัวละครปรากฏอยู่ในมาร์กอัปของคุณอาจเป็นปัญหาได้ หากคุณมีมันอยู่ภายในสตริง (เช่นnodeValueองค์ประกอบของ DOM ที่ไม่มีเนื้อหาที่มองเห็นได้) คุณอาจคาดหวังว่าสตริงดังกล่าวจะว่างเปล่าเมื่อจริง ๆ แล้วมันไม่ใช่ (แม้หลังจากนำไปใช้String.trim)

ZWSPยังสามารถทำให้ช่องว่างพิเศษปรากฏบนหน้า HTML ได้เช่นเมื่อพบระหว่างสอง<div>องค์ประกอบ (ดังที่เห็นในคำถามนี้ ) กรณีนี้ไม่สามารถทำซ้ำได้บน jsfiddle เนื่องจากอักขระจะถูกละเว้น

ปัญหาอื่นที่อาจเกิดขึ้น: หากการเข้ารหัสของหน้าเว็บไม่ได้รับการยอมรับว่าเป็น UTF-8 ตัวละครอาจปรากฏขึ้นจริง (เช่น ​ใน latin1 เป็นต้น)

หากZWSPมีอยู่ในโค้ด CSS (โค้ดอินไลน์หรือสไตล์ชีทภายนอก) สไตล์ก็ไม่สามารถแยกวิเคราะห์ได้อย่างเหมาะสมดังนั้นบางสไตล์จึงไม่ถูกนำไปใช้ (ดังที่เห็นในคำถามนี้ )

ข้อกำหนดของ ECMAScript

ฉันไม่สามารถพูดถึงตัวละครเฉพาะนั้นในข้อมูลจำเพาะ ECMAScript (รุ่น3และ5.1 ) เวอร์ชันปัจจุบันกล่าวถึงอักขระที่คล้ายกัน ( U+200CและU+200D) ในส่วน 7.1ซึ่งระบุว่าควรใช้เป็นIdentifierParts เมื่อ "อยู่นอกความคิดเห็นสตริงตัวอักษรและตัวอักษรนิพจน์ทั่วไป" ตัวอย่างเช่นตัวละครเหล่านั้นอาจเป็นส่วนหนึ่งของชื่อตัวแปร (และใช้var x\u200c;งานได้จริง)

ส่วน 7.2แสดงรายการอักขระช่องว่างที่ถูกต้อง (เช่นแท็บช่องว่างช่องว่างไม่แบ่ง ฯลฯ ) และกล่าวถึงราง ๆ ว่า Unicode อื่น ๆ "ช่องว่างแยก" (หมวดหมู่ "Zs") ควรได้รับการปฏิบัติเป็นพื้นที่สีขาว ฉันอาจไม่ใช่คนที่ดีที่สุดที่จะพูดคุยเกี่ยวกับรายละเอียดในเรื่องนี้ แต่ดูเหมือนว่าฉันU+200Bควรได้รับการพิจารณาพื้นที่สีขาวตามที่เมื่อในความเป็นจริงการใช้งาน (อย่างน้อย Chrome และ Firefox) ปรากฏขึ้นเพื่อถือว่าพวกเขาเป็นที่ไม่คาดคิด โทเค็น (หรือส่วนหนึ่งของ) ทำให้เกิดข้อผิดพลาดทางไวยากรณ์


codepen.io ยังปรากฏขึ้นเพื่อแสดงตัวละครนี้ VIM และ VI, notepad ++ ยังแสดงผล
rlemon

ขอบคุณ @rlemon เพิ่มตัวอย่าง CodePen ให้กับคำตอบ เว็บไซต์ที่ดีฉันไม่รู้เกี่ยวกับมัน
bfavaretto

พบปัญหามากขณะคัดลอก / วางรหัสสำหรับคลาส testTwo จากคำถาม SO นี้โดยใช้ Chromium เห็นได้ชัดว่า parser สำลักในการเน้นไวยากรณ์ของfunctionคำหลักซึ่งมองไม่เห็นใน Vim จนกว่าฉันจะเน้นมันโดยใช้คำถามที่พบบ่อย "เน้นทุกตัวอักษรที่ไม่สามารถพิมพ์ได้" อ่ามันจะดีมากถ้ามีวิธีที่จะคัดลอกตัวอักษรเท่านั้นในช่วงของ 32..127 ได้ ( แต่อาจมี app สำหรับ :) ว่า)
แอ๊

1
@bfavaretto เฉพาะในข้อมูลโค้ดในโหมดแก้ไข ไม่ได้อยู่ในเนื้อหาของคำถามที่ควรกล่าวถึงนี้ (ทดสอบใน Chrome 43.0.2357.124 m)
Fernando Leal

1
เครื่องมือแก้ไขข้อความหลายตัวอนุญาตให้สลับการเข้ารหัสอักขระของไฟล์ สิ่งนี้มีประโยชน์อย่างมากในการค้นหาตัวละครที่ละเมิด วิธีแก้ปัญหาของฉันคือเปลี่ยนจาก UTF-8 เป็นการเข้ารหัส ANSI เป็นการชั่วคราวลบอักขระที่ไม่ถูกต้องออกแล้วสลับกลับ ฉันใช้ฟรีแวร์ Notepad ++ บน Windows แก้ไข: ปรากฎว่าฉันพลาดตัวเลือก Notepad ++ สำหรับ "การแสดงตัวละครทั้งหมด" ผลลัพธ์เดียวกันลดความยุ่งยากน้อยลง: D
mbargiel

64

ทำไมคุณมองหาปัญหานี้ในรหัสของคุณ? แม้ว่ามันจะถูกคัดลอก

หากคุณเห็นสิ่งที่เกิดขึ้นหลังจากบันทึกไฟล์ในโฟลเดอร์ที่ซิงค์แล้วคุณจะเห็นสิ่ง*****ที่อยู่ท้ายไฟล์ มันไม่ได้เกี่ยวข้องกับรหัสของคุณเลย

สารละลาย.

หากคุณกำลังใช้งานnginxในกล่องคนจรจัด - เพิ่มในการกำหนดค่าเซิร์ฟเวอร์:

sendfile off;

หากคุณกำลังใช้งานapacheในกล่องคนจรจัด - เพิ่มในการกำหนดค่าเซิร์ฟเวอร์:

EnableSendfile Off;

ที่มาของปัญหา: ข้อผิดพลาด VirtualBox


6
คุณช่วยชีวิตฉันได้อย่างแท้จริง ฉันต่อสู้กับ Nginx + Vagrant มาทั้งคืนและมันก็แก้ไขได้
fradeve

2
ไม่ไม่คาดหวังนี้จะเป็นคำตอบที่เหมาะสม (สำหรับฉัน) แต่มันก็ขอบคุณมาก
Charlotte

2
จริงๆแล้วมันหยุดทำงาน จากนั้นอีกครั้งมี symlinking หลายเลเวลที่เล่นอยู่ที่นี่ดังนั้นฉันจึงเลิกทำในสิ่งที่ทำได้
Charlotte

ขอบคุณ - ฉันอยู่ในกล่องคนจรจัดที่มี nginx ฉันเคยเห็นปัญหานี้ในการตั้งค่า Apache ที่คล้ายกัน
คาเมรอน

สำหรับ apache: EnableSendfile Off
jamlee

7

สิ่งนี้อาจเกิดขึ้นหากคุณคัดลอกรหัสจากเอกสารอื่น (เช่น PDF) ลงในคอนโซลของคุณแล้วลองเรียกใช้

ฉันพยายามเรียกใช้โค้ดตัวอย่างจากหนังสือ Javascript ที่ฉันอ่านและรู้สึกประหลาดใจที่ไม่ได้ทำงานในคอนโซล

เห็นได้ชัดว่าการคัดลอกจาก PDF จะแนะนำตัวละครที่ไม่คาดคิดผิดกฎหมายและที่มองไม่เห็นเข้าไปในโค้ด


5

ฉันพบปัญหาเดียวกันกับ mac ของฉันและพบว่าเป็นเพราะ Mac ได้แทนที่เครื่องหมายคำพูดมาตรฐานด้วยคำพูดแบบโค้งซึ่งเป็นอักขระจาวาสคริปต์ที่ผิดกฎหมาย

ในการแก้ไขปัญหานี้ฉันต้องเปลี่ยนการตั้งค่าใน mac System Preferences => Keyboard => ข้อความ (แท็บ) ยกเลิกการเลือกใช้เครื่องหมายอัญประกาศและขีดกลางอัจฉริยะ (ตรวจสอบค่าเริ่มต้นแล้ว)


5

ฉันได้รับข้อผิดพลาดนี้ในโครเมี่ยมเมื่อฉันมีสตริงที่ไม่ถูกทำลายหลังจากบรรทัดที่ข้อผิดพลาดชี้ไป หลังจากปิดสตริงข้อผิดพลาดก็หายไป

ตัวอย่างที่มีข้อผิดพลาด:

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>";

ตัวอย่างที่ไม่มีข้อผิดพลาด:

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

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

2
ฉันต้องใช้ตัวอย่างที่แตกต่างกันสองอย่างของคุณเพื่อหาความแตกต่างและเมื่อฉันทำฉันก็จะพบปัญหาของฉันเองทันที
Ben Harold

3

หากคุณใช้งานโปรแกรมติดตั้ง nginx + uwsgi ปัญหาหลักคือข้อบกพร่องของกล่องเสมือนพร้อมไฟล์ส่งตามที่กล่าวไว้ในคำตอบบางส่วน อย่างไรก็ตามในการแก้ไขคุณต้องปิดการใช้งาน sendfile ทั้งใน nginx และ uwsgi

  1. ใน nginx.conf sendfile ปิด

  2. แอปพลิเคชั่น uwsgi / config --disable-sendfile


2

เมื่อเรียกใช้ OS X ระบบไฟล์จะสร้างส้อมที่ซ่อนของไฟล์ทั้งหมดของคุณหากอยู่ในฮาร์ดไดรฟ์ที่ไม่รองรับ HFS ​​+ บางครั้งสิ่งนี้สามารถเกิดขึ้นกับฉันตอนนี้นำไปสู่เครื่องมือ JavaScript ของคุณพยายามเรียกใช้ data-fork แทนรหัสที่คุณต้องการให้รัน เมื่อสิ่งนี้เกิดขึ้นคุณจะได้รับ

SyntaxError: Unexpected token ILLEGAL

เนื่องจากตัวแยกข้อมูลของไฟล์ของคุณจะมีอักขระ Unicode U + 200B การลบไฟล์ data fork จะทำให้สคริปต์ของคุณรันโค้ดจริงของคุณแทนที่จะเป็น data fork แบบไบนารีของโค้ดของคุณ

. อะไรก็ตาม: ไฟล์เหล่านี้ถูกสร้างขึ้นในโวลุ่มที่ไม่สนับสนุนคุณสมบัติของไฟล์ HFS แบบเต็ม (เช่นวอลุ่ม ufs, ไฟล์แชร์ของ Windows เป็นต้น) เมื่อไฟล์ Mac ถูกคัดลอกไปยังโวลุ่มดังกล่าวตัวแยกข้อมูลจะถูกจัดเก็บภายใต้ชื่อปกติของไฟล์และข้อมูล HFS เพิ่มเติม (ตัวแยกทรัพยากรประเภท & รหัสผู้สร้าง ฯลฯ ) จะถูกเก็บไว้ในไฟล์ที่สอง (ในรูปแบบ AppleDouble) ด้วยชื่อที่ขึ้นต้นด้วย ". " (แน่นอนว่าไฟล์เหล่านี้จะมองไม่เห็นเท่าที่เกี่ยวข้องกับ OS-X แต่ไม่เกี่ยวข้องกับระบบปฏิบัติการอื่น ๆ บางครั้งอาจทำให้เกิดความรำคาญ ... )


1

นี่คือเหตุผลของฉัน:

ก่อน:

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

ซึ่ง\uเป็นการหลบหนีฉันคิดออกโดยใช้การวิเคราะห์ของCodepen JS

หลังจาก:

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

และข้อผิดพลาดคงที่


0

ฉันมีปัญหาเดียวกันนี้และมันเกิดขึ้นเพราะฉันกดปุ่ม Enter เมื่อเพิ่มรหัสในสตริงข้อความ

เพราะมันเป็นข้อความที่ยาวมากฉันต้องการเห็นมันทั้งหมดโดยไม่ต้องเลื่อนใน text editor ของฉัน แต่การกดปุ่ม enter ก็เพิ่มตัวละครที่มองไม่เห็นลงในสตริงซึ่งผิดกฎหมาย ฉันใช้ Sublime Text เป็นเครื่องมือแก้ไข


0

ฉันเปลี่ยนพื้นที่ทั้งหมดเป็น & nbsp ก็เป็นเช่นนั้นและทำงานได้โดยไม่มีปัญหา

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

ฉันหวังว่ามันจะช่วยให้ใครบางคน


0

ฉันจะเพิ่มคำตอบอีกหนึ่งกอง ปัญหานี้อาจเกิดขึ้นได้เนื่องจากการเข้ารหัส คุณต้องการเข้ารหัส utf8 ให้ปลอดภัย ผู้แก้ไขบางคนใช้ค่าเริ่มต้น utf16 ซึ่งอาจทำให้เกิดปัญหา วิธีหนึ่งที่รวดเร็วในการทดสอบสิ่งนี้คือตัวอย่างในรหัส VS เพียงแค่สร้างเนื้อหาเดียวกัน แต่ใช้ตัวแก้ไขโลคัลของ vscode เพื่อสร้างไฟล์ หวังว่านี่จะช่วยได้บ้าง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.