“ ’” แสดงบนหน้าแทนที่จะเป็น“ '”


133

’'มีการแสดงบนหน้าเว็บของฉันแทน

ฉันContent-Typeตั้งค่าเป็นUTF-8ทั้งใน<head>แท็กและส่วนหัว HTTP ของฉัน:

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

ป้อนคำอธิบายภาพที่นี่

นอกจากนี้เบราว์เซอร์ของฉันถูกตั้งค่าเป็นUnicode (UTF-8):

ป้อนคำอธิบายภาพที่นี่

ปัญหาคืออะไรและฉันจะแก้ไขได้อย่างไร


คำตอบ:


55

ตรวจสอบให้แน่ใจว่าเบราว์เซอร์และโปรแกรมแก้ไขใช้การเข้ารหัส UTF-8 แทน ISO-8859-1 / Windows-1252

หรือใช้&rsquo;.


75
ไม่ใช่มันไม่ได้แก้ไข ยังคงมีความไม่สอดคล้องกันในการเข้ารหัสอักขระในแอปพลิเคชันของคุณ คุณจะพบปัญหาเดิมอีกครั้งในอนาคตสำหรับอักขระอื่น ๆ ที่ไม่ใช่ CP1252 และมีจำนวนมากทีเดียว ...
BalusC

12
ตัวอย่างตัวละครที่คุณจะพบต่อไป: i18nqa.com/debug/utf8-debug.html
Zoot

การเข้ารหัส utf-8 +1
Karuhanga

217

แล้วปัญหาคืออะไร

มันเป็น( RIGHT SINGLE QUOTATION MARK- U + 2019) ตัวละครที่จะถูกถอดรหัสเป็นCP-1252แทนUTF-8 หากคุณตรวจสอบการเข้ารหัสตารางแล้วคุณจะเห็นว่าตัวละครตัวนี้เป็น UTF-8 ประกอบด้วยไบต์0xE2, และ0x80 0x99หากคุณตรวจสอบรูปแบบ CP-1252 รหัสของหน้าแล้วคุณจะเห็นว่าแต่ละไบต์ผู้ที่ยืนสำหรับตัวละครแต่ละบุคคลâ, และ


และจะแก้ไขได้อย่างไร?

ใช้ UTF-8 แทน CP-1252 เพื่ออ่านเขียนจัดเก็บและแสดงอักขระ


ฉันตั้งค่า Content-Type เป็น UTF-8 ทั้งใน<head>แท็กและส่วนหัว HTTP ของฉัน:

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

สิ่งนี้จะสั่งเฉพาะไคลเอ็นต์ที่จะใช้การเข้ารหัสเพื่อตีความและแสดงอักขระ สิ่งนี้ไม่ได้สั่งให้โปรแกรมของคุณเองที่จะใช้การเข้ารหัสเพื่ออ่านเขียนจัดเก็บและแสดงอักขระคำตอบที่แน่นอนขึ้นอยู่กับแพลตฟอร์ม / ฐานข้อมูล / ภาษาโปรแกรมที่ใช้ในฝั่งเซิร์ฟเวอร์ โปรดทราบว่าชุดหนึ่งในส่วนหัวการตอบกลับ HTTP มีความสำคัญเหนือเมตาแท็ก HTML เมตาแท็ก HTML จะใช้ก็ต่อเมื่อเปิดเพจจากระบบไฟล์โลคัลดิสก์แทนที่จะใช้จาก HTTP


นอกจากนี้เบราว์เซอร์ของฉันถูกตั้งค่าเป็นUnicode (UTF-8):

สิ่งนี้บังคับเฉพาะไคลเอ็นต์ที่ใช้การเข้ารหัสเพื่อตีความและแสดงอักขระ แต่ปัญหาที่เกิดขึ้นจริงคือการที่คุณจะส่งแล้ว’(เข้ารหัสใน UTF-8) ให้กับลูกค้าแทน ไคลเอ็นต์แสดงอย่างถูกต้อง’โดยใช้การเข้ารหัส UTF-8 หากไคลเอ็นต์ถูกกำหนดให้ใช้ผิดเช่น ISO-8859-1 คุณน่าจะได้เห็นââ¬â¢แทน


ฉันใช้ ASP.NET 2.0 กับฐานข้อมูล

ปัญหานี้เป็นไปได้มากที่สุด คุณต้องตรวจสอบด้วยเครื่องมือฐานข้อมูลอิสระว่าข้อมูลมีลักษณะอย่างไร

หากมีอักขระแสดงว่าคุณเชื่อมต่อกับฐานข้อมูลไม่ถูกต้อง คุณต้องบอกให้ตัวเชื่อมต่อฐานข้อมูลใช้ UTF-8

หากฐานข้อมูลของคุณมี’นั่นแสดงว่าฐานข้อมูลของคุณยุ่งเหยิง UTF-8ส่วนใหญ่อาจตารางไม่ได้กำหนดค่ากับการใช้งาน แต่จะใช้การเข้ารหัสเริ่มต้นของฐานข้อมูลซึ่งแตกต่างกันไปตามการกำหนดค่า หากนี่เป็นปัญหาของคุณโดยปกติแล้วการปรับเปลี่ยนตารางเพื่อใช้ UTF-8 ก็เพียงพอแล้ว หากฐานข้อมูลของคุณไม่รองรับคุณจะต้องสร้างตารางใหม่ เป็นแนวทางปฏิบัติที่ดีในการตั้งค่าการเข้ารหัสของตารางเมื่อคุณสร้างตาราง

คุณมักจะใช้ SQL Server แต่นี่คือรหัส MySQL (คัดลอกมาจากบทความนี้ ):

CREATE DATABASE db_name CHARACTER SET utf8;
CREATE TABLE tbl_name (...) CHARACTER SET utf8;

หากตารางของคุณเป็น UTF-8 อยู่แล้วคุณจะต้องถอยหลัง ใครหรืออะไรใส่ข้อมูลไว้ที่นั่น นั่นคือจุดที่เป็นปัญหา ตัวอย่างหนึ่งคือค่าที่ส่งในรูปแบบ HTML ซึ่งเข้ารหัส / ถอดรหัสไม่ถูกต้อง


ลิงก์เพิ่มเติมเพื่อเรียนรู้เพิ่มเติมเกี่ยวกับปัญหามีดังนี้


2
หากคุณมีเนื้อหาที่เสียหายเช่นนี้บันทึกไว้ที่ไหนสักแห่งเช่นในฐานข้อมูล mysql stackoverflow.com/a/9407998/117647มีเคล็ดลับที่คุณต้องแปลงอักขระเป็น utf-8
Steve

5
TL; DR; ใช้ UTF-8 เพื่ออ่านเขียนจัดเก็บและแสดงอักขระ
c0degeas

โปรดสังเกตว่าตาราง iso-8859-1 และ Windows-1252 ทับซ้อนกันดังนั้น "ชุดอักขระแปลก ๆ " บางตัวจึงเป็นเรื่องปกติสำหรับทั้งสองอย่าง (เช่น "é" สำหรับ "é")
Skippy le Grand Gourou

15

ฉันมีเอกสารบางอย่างที่ได้แสดงเป็น…และได้แสดงเป็นê êนี่คือวิธีไปที่นั่น (รหัส python):

# Adam edits original file using windows-1252
windows = '\x85\xea' 
# that is HORIZONTAL ELLIPSIS, LATIN SMALL LETTER E WITH CIRCUMFLEX

# Beth reads it correctly as windows-1252 and writes it as utf-8
utf8 = windows.decode("windows-1252").encode("utf-8")
print(utf8)

# Charlie reads it *incorrectly* as windows-1252 writes a twingled utf-8 version
twingled = utf8.decode("windows-1252").encode("utf-8")
print(twingled)

# detwingle by reading as utf-8 and writing as windows-1252 (it's really utf-8)
detwingled = twingled.decode("utf-8").encode("windows-1252")

assert utf8==detwingled

เพื่อแก้ไขปัญหาฉันใช้รหัส python ดังนี้:

with open("dirty.html","rb") as f:
    dt = f.read()
ct = dt.decode("utf8").encode("windows-1252")
with open("clean.html","wb") as g:
    g.write(ct)

(เนื่องจากมีคนใส่เวอร์ชันที่บิดเบี้ยวลงในเอกสาร UTF-8 ที่ถูกต้องจริงๆแล้วฉันต้องดึงเฉพาะส่วนที่บิดเบี้ยวออกจากกันแล้วใส่กลับเข้าไปฉันใช้ BeautifulSoup สำหรับสิ่งนี้)

มีความเป็นไปได้สูงที่คุณจะมี Charlie ในการสร้างเนื้อหามากกว่าที่การกำหนดค่าเว็บเซิร์ฟเวอร์ไม่ถูกต้อง คุณยังสามารถบังคับให้เว็บเบราว์เซอร์ของคุณบิดหน้าได้โดยเลือกการเข้ารหัส windows-1252 สำหรับเอกสาร utf-8 เว็บเบราว์เซอร์ของคุณไม่สามารถแยกเอกสารที่ Charlie บันทึกไว้

หมายเหตุ : ปัญหาเดียวกันนี้อาจเกิดขึ้นกับหน้ารหัสไบต์เดี่ยวอื่น ๆ (เช่น latin-1) แทนที่จะเป็น windows-1252


15

(Unicode codepoint U+2019 RIGHT SINGLE QUOTATION MARK) ถูกเข้ารหัสใน UTF-8 เป็นไบต์:

0xE2 0x80 0x99.

’(Unicode codepoints U+00E2 U+20AC U+2122) ถูกเข้ารหัสใน UTF-8 เป็นไบต์:

0xC3 0xA2   0xE2 0x82 0xAC   0xE2 0x84 0xA2.

นี่คือไบต์ที่เบราว์เซอร์ของคุณได้รับจริงเพื่อผลิต ’เมื่อประมวลผลเป็น UTF-8

นั่นหมายความว่าแหล่งข้อมูลของคุณกำลังผ่านการแปลงชุดอักขระสองชุดก่อนที่จะส่งไปยังเบราว์เซอร์:

  1. อักขระต้นทาง( U+2019) ถูกเข้ารหัสครั้งแรกเป็น UTF-8 ไบต์:

    0xE2 0x80 0x99

  2. ไบต์แต่ละไบต์เหล่านั้นถูกตีความผิดและถอดรหัสเป็น Unicode codepoints U+00E2 U+20AC U+2122โดยหนึ่งในชุดอักขระของWindows-125X (1252, 1254, 1256 และ 1258 0xE2 0x80 0x99จะแมปทั้งหมดU+00E2 U+20AC U+2122) จากนั้นจุดรหัสเหล่านั้นจะถูกเข้ารหัสเป็น UTF-8 ไบต์:

    0xE2-> U+00E2-> 0xC3 0xA2
    0x80-> U+20AC-> 0xE2 0x82 0xAC
    0x99-> U+2122->0xE2 0x84 0xA2

คุณต้องหาว่าการแปลงเพิ่มเติมในขั้นตอนที่ 2 กำลังดำเนินการอยู่ที่ใดและนำออก


12

บางครั้งอาจเกิดขึ้นเมื่อมีการแปลงสตริงจาก Windows-1252 เป็น UTF-8 สองครั้งสองครั้ง

เรามีสิ่งนี้ในแอปพลิเคชัน Zend / PHP / MySQL ที่มีอักขระแบบนั้นปรากฏในฐานข้อมูลอาจเนื่องมาจากการเชื่อมต่อ MySQL ไม่ได้ระบุชุดอักขระที่ถูกต้อง เราต้อง:

  1. ตรวจสอบให้แน่ใจว่า Zend และ PHP กำลังสื่อสารกับฐานข้อมูลใน UTF-8 ( ไม่ใช่ค่าเริ่มต้น)

  2. ซ่อมแซมอักขระที่เสียด้วยการสืบค้น SQL หลายรายการเช่นนี้ ...

    UPDATE MyTable SET 
    MyField1 = CONVERT(CAST(CONVERT(MyField1 USING latin1) AS BINARY) USING utf8),
    MyField2 = CONVERT(CAST(CONVERT(MyField2 USING latin1) AS BINARY) USING utf8);
    

    ทำสิ่งนี้กับตาราง / คอลัมน์ให้มากที่สุดเท่าที่จำเป็น

คุณยังสามารถแก้ไขบางส่วนของสตริงเหล่านี้ใน PHP ได้หากจำเป็น โปรดทราบว่าเนื่องจากอักขระถูกเข้ารหัสสองครั้งเราจึงต้องทำการแปลงย้อนกลับจาก UTF-8 กลับไปเป็น Windows-1252 ซึ่งทำให้ฉันสับสนในตอนแรก

mb_convert_encoding('’', 'Windows-1252', 'UTF-8');    // returns ’

9

คุณมีความไม่ตรงกันในการเข้ารหัสอักขระของคุณ สตริงของคุณถูกเข้ารหัสด้วยการเข้ารหัสเดียว (UTF-8) และสิ่งใดก็ตามที่ตีความหน้านี้จะใช้อีกอันหนึ่ง (เช่น ASCII)

ระบุการเข้ารหัสของคุณในส่วนหัว http เสมอและตรวจสอบให้แน่ใจว่าสิ่งนี้ตรงกับนิยามการเข้ารหัสของกรอบงานของคุณ

ตัวอย่าง http ส่วนหัว:

Content-Type    text/html; charset=utf-8

การตั้งค่าการเข้ารหัสใน asp.net

<configuration>
  <system.web>
    <globalization
      fileEncoding="utf-8"
      requestEncoding="utf-8"
      responseEncoding="utf-8"
      culture="en-US"
      uiCulture="de-DE"
    />
  </system.web>
</configuration>

การตั้งค่าการเข้ารหัสใน jsp


7

หากประเภทเนื้อหาของคุณเป็น UTF8 อยู่แล้วแสดงว่าข้อมูลนั้นมีการเข้ารหัสที่ไม่ถูกต้องอยู่แล้ว หากคุณกำลังรับข้อมูลจากฐานข้อมูลตรวจสอบให้แน่ใจว่าการเชื่อมต่อฐานข้อมูลใช้ UTF-8

หากเป็นข้อมูลจากไฟล์ตรวจสอบให้แน่ใจว่าไฟล์นั้นเข้ารหัสอย่างถูกต้องเป็น UTF-8 โดยปกติคุณสามารถตั้งค่านี้ได้ในกล่องโต้ตอบ "บันทึกเป็น ... " ของตัวแก้ไขที่คุณเลือก

หากข้อมูลเสียอยู่แล้วเมื่อคุณดูในไฟล์ต้นฉบับอาจเป็นไปได้ว่าข้อมูลนั้นเคยเป็นไฟล์ UTF-8 แต่ถูกบันทึกด้วยการเข้ารหัสที่ไม่ถูกต้องระหว่างทาง


4

หากมีคนได้รับข้อผิดพลาดนี้ในเว็บไซต์ WordPress คุณต้องเปลี่ยน wp-config db charset:

define('DB_CHARSET', 'utf8mb4_unicode_ci');

แทน:

define('DB_CHARSET', 'utf8mb4');

0

ใน DBeaver (หรือตัวแก้ไขอื่น ๆ ) ไฟล์สคริปต์ที่คุณกำลังทำงานสามารถแจ้งให้บันทึกเป็น UTF8 และจะเปลี่ยนถ่าน:

–

เข้าไป

–

หรือ

–

-1

คุณต้องคัดลอก / วางข้อความจากเอกสาร Word เอกสาร Word ใช้ Smart Quotes คุณสามารถแทนที่ด้วยอักขระพิเศษ (& rsquo;) หรือพิมพ์ในโปรแกรมแก้ไข HTML ของคุณ (')

ฉันมั่นใจว่านี่จะช่วยแก้ปัญหาของคุณได้


-3

สิ่งเดียวกันนี้เกิดขึ้นกับฉันด้วยอักขระ "-" (เครื่องหมายลบแบบยาว)
ฉันใช้การแทนที่อย่างง่ายนี้เพื่อแก้ไข:

htmlText = htmlText.Replace('–', '-');

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